/* * Copyright (C) 2011 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "RenderServer.h" #include "TcpStream.h" #ifdef _WIN32 #include "Win32PipeStream.h" #else #include "UnixStream.h" #endif #include "RenderThread.h" #include "FrameBuffer.h" #include <set> typedef std::set<RenderThread *> RenderThreadsSet; RenderServer::RenderServer() : m_listenSock(NULL), m_exiting(false) { } extern "C" int gRendererStreamMode; RenderServer *RenderServer::create(int port) { RenderServer *server = new RenderServer(); if (!server) { return NULL; } if (gRendererStreamMode == STREAM_MODE_TCP) { server->m_listenSock = new TcpStream(); } else { #ifdef _WIN32 server->m_listenSock = new Win32PipeStream(); #else server->m_listenSock = new UnixStream(); #endif } if (server->m_listenSock->listen(port) < 0) { ERR("RenderServer::create failed to listen on port %d\n", port); delete server; return NULL; } return server; } int RenderServer::Main() { RenderThreadsSet threads; while(1) { SocketStream *stream = m_listenSock->accept(); if (!stream) { fprintf(stderr,"Error accepting connection, aborting\n"); break; } unsigned int clientFlags; if (!stream->readFully(&clientFlags, sizeof(unsigned int))) { fprintf(stderr,"Error reading clientFlags\n"); delete stream; continue; } DBG("\n\n\n\n Got new stream!!!! \n\n\n\n\n"); // check if we have been requested to exit while waiting on accept if ((clientFlags & IOSTREAM_CLIENT_EXIT_SERVER) != 0) { m_exiting = true; break; } RenderThread *rt = RenderThread::create(stream); if (!rt) { fprintf(stderr,"Failed to create RenderThread\n"); delete stream; } if (!rt->start()) { fprintf(stderr,"Failed to start RenderThread\n"); delete stream; delete rt; } // // remove from the threads list threads which are // no longer running // for (RenderThreadsSet::iterator n,t = threads.begin(); t != threads.end(); t = n) { // first find next iterator n = t; n++; // delete and erase the current iterator // if thread is no longer running if ((*t)->isFinished()) { delete (*t); threads.erase(t); } } // insert the added thread to the list threads.insert(rt); DBG("Started new RenderThread\n"); } // // Wait for all threads to finish // for (RenderThreadsSet::iterator t = threads.begin(); t != threads.end(); t++) { int exitStatus; (*t)->wait(&exitStatus); delete (*t); } threads.clear(); // // de-initialize the FrameBuffer object // FrameBuffer::finalize(); return 0; }