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