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
35 extern "C" int gRendererStreamMode;
36
create(int port)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
Main()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