Home | History | Annotate | Download | only in libOpenglRender
      1 /*
      2 * Copyright (C) 2011 The Android Open Source Project
      3 *
      4 * Licensed under the Apache License, Version 2.0 (the "License");
      5 * you may not use this file except in compliance with the License.
      6 * You may obtain a copy of the License at
      7 *
      8 * http://www.apache.org/licenses/LICENSE-2.0
      9 *
     10 * Unless required by applicable law or agreed to in writing, software
     11 * distributed under the License is distributed on an "AS IS" BASIS,
     12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 * See the License for the specific language governing permissions and
     14 * limitations under the License.
     15 */
     16 #include "RenderServer.h"
     17 #include "TcpStream.h"
     18 #ifdef _WIN32
     19 #include "Win32PipeStream.h"
     20 #else
     21 #include "UnixStream.h"
     22 #endif
     23 #include "RenderThread.h"
     24 #include "FrameBuffer.h"
     25 #include <set>
     26 
     27 typedef std::set<RenderThread *> RenderThreadsSet;
     28 
     29 RenderServer::RenderServer() :
     30     m_listenSock(NULL),
     31     m_exiting(false)
     32 {
     33 }
     34 
     35 extern "C" int gRendererStreamMode;
     36 
     37 RenderServer *RenderServer::create(int port)
     38 {
     39     RenderServer *server = new RenderServer();
     40     if (!server) {
     41         return NULL;
     42     }
     43 
     44     if (gRendererStreamMode == STREAM_MODE_TCP) {
     45         server->m_listenSock = new TcpStream();
     46     } else {
     47 #ifdef _WIN32
     48         server->m_listenSock = new Win32PipeStream();
     49 #else
     50         server->m_listenSock = new UnixStream();
     51 #endif
     52     }
     53 
     54     if (server->m_listenSock->listen(port) < 0) {
     55         ERR("RenderServer::create failed to listen on port %d\n", port);
     56         delete server;
     57         return NULL;
     58     }
     59 
     60     return server;
     61 }
     62 
     63 int RenderServer::Main()
     64 {
     65     RenderThreadsSet threads;
     66 
     67     while(1) {
     68         SocketStream *stream = m_listenSock->accept();
     69         if (!stream) {
     70             fprintf(stderr,"Error accepting connection, aborting\n");
     71             break;
     72         }
     73 
     74         unsigned int clientFlags;
     75         if (!stream->readFully(&clientFlags, sizeof(unsigned int))) {
     76             fprintf(stderr,"Error reading clientFlags\n");
     77             delete stream;
     78             continue;
     79         }
     80 
     81         DBG("\n\n\n\n Got new stream!!!! \n\n\n\n\n");
     82         // check if we have been requested to exit while waiting on accept
     83         if ((clientFlags & IOSTREAM_CLIENT_EXIT_SERVER) != 0) {
     84             m_exiting = true;
     85             break;
     86         }
     87 
     88         RenderThread *rt = RenderThread::create(stream);
     89         if (!rt) {
     90             fprintf(stderr,"Failed to create RenderThread\n");
     91             delete stream;
     92         }
     93 
     94         if (!rt->start()) {
     95             fprintf(stderr,"Failed to start RenderThread\n");
     96             delete stream;
     97             delete rt;
     98         }
     99 
    100         //
    101         // remove from the threads list threads which are
    102         // no longer running
    103         //
    104         for (RenderThreadsSet::iterator n,t = threads.begin();
    105              t != threads.end();
    106              t = n) {
    107             // first find next iterator
    108             n = t;
    109             n++;
    110 
    111             // delete and erase the current iterator
    112             // if thread is no longer running
    113             if ((*t)->isFinished()) {
    114                 delete (*t);
    115                 threads.erase(t);
    116             }
    117         }
    118 
    119         // insert the added thread to the list
    120         threads.insert(rt);
    121 
    122         DBG("Started new RenderThread\n");
    123     }
    124 
    125     //
    126     // Wait for all threads to finish
    127     //
    128     for (RenderThreadsSet::iterator t = threads.begin();
    129          t != threads.end();
    130          t++) {
    131         int exitStatus;
    132         (*t)->wait(&exitStatus);
    133         delete (*t);
    134     }
    135     threads.clear();
    136 
    137     //
    138     // de-initialize the FrameBuffer object
    139     //
    140     FrameBuffer::finalize();
    141     return 0;
    142 }
    143