• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
RenderServer()29 RenderServer::RenderServer() :
30     m_listenSock(NULL),
31     m_exiting(false)
32 {
33 }
34 
~RenderServer()35 RenderServer::~RenderServer()
36 {
37     delete m_listenSock;
38 }
39 
40 
41 extern "C" int gRendererStreamMode;
42 
create(char * addr,size_t addrLen)43 RenderServer *RenderServer::create(char* addr, size_t addrLen)
44 {
45     RenderServer *server = new RenderServer();
46     if (!server) {
47         return NULL;
48     }
49 
50     if (gRendererStreamMode == STREAM_MODE_TCP) {
51         server->m_listenSock = new TcpStream();
52     } else {
53 #ifdef _WIN32
54         server->m_listenSock = new Win32PipeStream();
55 #else
56         server->m_listenSock = new UnixStream();
57 #endif
58     }
59 
60     char addrstr[SocketStream::MAX_ADDRSTR_LEN];
61     if (server->m_listenSock->listen(addrstr) < 0) {
62         ERR("RenderServer::create failed to listen\n");
63         delete server;
64         return NULL;
65     }
66 
67     size_t len = strlen(addrstr) + 1;
68     if (len > addrLen) {
69         ERR("RenderServer address name too big for provided buffer: %zu > %zu\n",
70                 len, addrLen);
71         delete server;
72         return NULL;
73     }
74     memcpy(addr, addrstr, len);
75 
76     return server;
77 }
78 
Main()79 int RenderServer::Main()
80 {
81     RenderThreadsSet threads;
82 
83     while(1) {
84         SocketStream *stream = m_listenSock->accept();
85         if (!stream) {
86             fprintf(stderr,"Error accepting connection, aborting\n");
87             break;
88         }
89 
90         unsigned int clientFlags;
91         if (!stream->readFully(&clientFlags, sizeof(unsigned int))) {
92             fprintf(stderr,"Error reading clientFlags\n");
93             delete stream;
94             continue;
95         }
96 
97         DBG("RenderServer: Got new stream!\n");
98 
99         // check if we have been requested to exit while waiting on accept
100         if ((clientFlags & IOSTREAM_CLIENT_EXIT_SERVER) != 0) {
101             m_exiting = true;
102             break;
103         }
104 
105         RenderThread *rt = RenderThread::create(stream);
106         if (!rt) {
107             fprintf(stderr,"Failed to create RenderThread\n");
108             delete stream;
109         }
110 
111         if (!rt->start()) {
112             fprintf(stderr,"Failed to start RenderThread\n");
113             delete stream;
114             delete rt;
115         }
116 
117         //
118         // remove from the threads list threads which are
119         // no longer running
120         //
121         for (RenderThreadsSet::iterator n,t = threads.begin();
122              t != threads.end();
123              t = n) {
124             // first find next iterator
125             n = t;
126             n++;
127 
128             // delete and erase the current iterator
129             // if thread is no longer running
130             if ((*t)->isFinished()) {
131                 delete (*t);
132                 threads.erase(t);
133             }
134         }
135 
136         // insert the added thread to the list
137         threads.insert(rt);
138 
139         DBG("Started new RenderThread\n");
140     }
141 
142     //
143     // Wait for all threads to finish
144     //
145     for (RenderThreadsSet::iterator t = threads.begin();
146          t != threads.end();
147          t++) {
148         int exitStatus;
149         (*t)->wait(&exitStatus);
150         delete (*t);
151     }
152     threads.clear();
153 
154     //
155     // de-initialize the FrameBuffer object
156     //
157     FrameBuffer::finalize();
158     return 0;
159 }
160