| /* |
| * 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; |
| } |