00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "cslib/CSConfig.h"
00030
00031 #include "defs_ms.h"
00032
00033 #include "cslib/CSGlobal.h"
00034 #include "cslib/CSLog.h"
00035
00036 #include "network_ms.h"
00037 #include "connection_handler_ms.h"
00038
00039 MSSystemThread *MSNetwork::gSystemThread;
00040 time_t MSNetwork::gCurrentTime;
00041 time_t MSNetwork::gLastService;
00042 CSThreadList *MSNetwork::gHandlerList;
00043 CSSync MSNetwork::gListenerLock;
00044 CSSocket *MSNetwork::gListenerSocket;
00045 MSConnectionHandler *MSNetwork::gListenerThread;
00046 uint32_t MSNetwork::gWaitingToListen;
00047 int MSNetwork::handlerCount;
00048
00049
00050
00051
00052
00053
00054 bool MSSystemThread::doWork()
00055 {
00056 bool killed = true;
00057
00058 enter_();
00059 MSNetwork::gCurrentTime = time(NULL);
00060 if ((MSNetwork::gCurrentTime - MSNetwork::gLastService) >= (MS_IDLE_THREAD_TIMEOUT/2)) {
00061 MSNetwork::gLastService = MSNetwork::gCurrentTime;
00062 while (!myMustQuit && killed) {
00063 killed = MSNetwork::killListener();
00064 MSNetwork::gCurrentTime = time(NULL);
00065 }
00066 }
00067 return_(true);
00068 }
00069
00070
00071
00072
00073
00074
00075 void MSNetwork::startUp(int port)
00076 {
00077 enter_();
00078 gCurrentTime = time(NULL);
00079 gLastService = gCurrentTime;
00080 gListenerSocket = NULL;
00081 handlerCount = 0;
00082
00083 CSL.lock();
00084 CSL.log(self, CSLog::Protocol, "Media Stream Daemon ");
00085 if (port) {
00086 CSL.log(self, CSLog::Protocol, " listening on port ");
00087 CSL.log(self, CSLog::Protocol, port);
00088 } else
00089 CSL.log(self, CSLog::Protocol, " not published ");
00090 CSL.log(self, CSLog::Protocol, "\n");
00091 CSL.unlock();
00092
00093 new_(gHandlerList, CSThreadList());
00094 if (port) {
00095 gListenerSocket = CSSocket::newSocket();
00096 gListenerSocket->publish(NULL, port);
00097 } else
00098 gListenerSocket = NULL;
00099
00100 new_(gSystemThread, MSSystemThread(1000 , NULL));
00101 gSystemThread->start();
00102 exit_();
00103 }
00104
00105 void MSNetwork::shutDown()
00106 {
00107 enter_();
00108
00109 if (gSystemThread) {
00110 gSystemThread->stop();
00111 gSystemThread->release();
00112 gSystemThread = NULL;
00113 }
00114
00115
00116 if (gHandlerList)
00117 gHandlerList->quitAllThreads();
00118
00119
00120 if (gListenerThread)
00121 gListenerThread->shuttingDown = true;
00122
00123 lock_(&gListenerLock);
00124 if (gListenerSocket) {
00125 try_(a) {
00126 gListenerSocket->release();
00127 }
00128 catch_(a) {
00129 self->logException();
00130 }
00131 cont_(a);
00132 }
00133 gListenerSocket = NULL;
00134 unlock_(&gListenerLock);
00135
00136 if (gHandlerList) {
00137 try_(b) {
00138
00139 gHandlerList->release();
00140 }
00141 catch_(b) {
00142 self->logException();
00143 }
00144 cont_(b);
00145 }
00146
00147 CSL.log(self, CSLog::Protocol, "PrimeBase Media Stream Daemon no longer published\n");
00148 exit_();
00149 }
00150
00151 void MSNetwork::startConnectionHandler()
00152 {
00153 char buffer[120];
00154 MSConnectionHandler *thread;
00155
00156 enter_();
00157 handlerCount++;
00158 snprintf(buffer, 120, "NetworkHandler%d", handlerCount);
00159 lock_(gHandlerList);
00160 thread = MSConnectionHandler::newHandler(MSNetwork::gHandlerList);
00161 unlock_(gHandlerList);
00162 push_(thread);
00163 thread->threadName = CSString::newString(buffer);
00164 thread->start();
00165 release_(thread);
00166 exit_();
00167 }
00168
00169
00170
00171
00172
00173 class OpenConnectioCleanUp : public CSRefObject {
00174 bool do_cleanup;
00175
00176 public:
00177
00178 OpenConnectioCleanUp(): CSRefObject(),
00179 do_cleanup(false){}
00180
00181 ~OpenConnectioCleanUp()
00182 {
00183 if (do_cleanup) {
00184 MSNetwork::unlockListenerSocket();
00185 }
00186 }
00187
00188 void setCleanUp()
00189 {
00190 do_cleanup = true;
00191 }
00192
00193 void cancelCleanUp()
00194 {
00195 do_cleanup = false;
00196 }
00197
00198 };
00199
00200
00201
00202
00203
00204 CSSocket *MSNetwork::openConnection(MSConnectionHandler *handler)
00205 {
00206 CSSocket *sock = NULL;
00207 OpenConnectioCleanUp *cleanup;
00208
00209 enter_();
00210
00211 if(!MSNetwork::gListenerSocket) {
00212 return_(NULL);
00213 }
00214
00215 sock = CSSocket::newSocket();
00216 push_(sock);
00217
00218
00219 if (!lockListenerSocket(handler)) {
00220 release_(sock);
00221 return_(NULL);
00222 }
00223
00224 new_(cleanup, OpenConnectioCleanUp());
00225 push_(cleanup);
00226
00227 cleanup->setCleanUp();
00228 sock->open(MSNetwork::gListenerSocket);
00229 cleanup->cancelCleanUp();
00230
00231 handler->lastUse = gCurrentTime;
00232
00233 unlockListenerSocket();
00234
00235 release_(cleanup);
00236 pop_(sock);
00237 return_(sock);
00238 }
00239
00240 void MSNetwork::startNetwork()
00241 {
00242 enter_();
00243 startConnectionHandler();
00244 exit_();
00245 }
00246
00247 bool MSNetwork::lockListenerSocket(MSConnectionHandler *handler)
00248 {
00249 bool socket_locked = false;
00250
00251 enter_();
00252 if (handler->myMustQuit)
00253 return false;
00254 lock_(&gListenerLock);
00255 if (gListenerSocket) {
00256
00257 if (gListenerThread) {
00258 gWaitingToListen++;
00259 handler->amWaitingToListen = true;
00260 while (gListenerThread) {
00261 if (handler->myMustQuit)
00262 break;
00263 try_(a) {
00264 gListenerLock.wait(2000);
00265 }
00266 catch_(a) {
00267 ;
00268 }
00269 cont_(a);
00270 }
00271 gWaitingToListen--;
00272 handler->amWaitingToListen = false;
00273 }
00274 if (!handler->myMustQuit) {
00275 gListenerThread = handler;
00276 socket_locked = true;
00277 }
00278 }
00279 unlock_(&gListenerLock);
00280 return_(socket_locked);
00281 }
00282
00283 void MSNetwork::unlockListenerSocket()
00284 {
00285 enter_();
00286 lock_(&gListenerLock);
00287 gListenerThread = NULL;
00288 gListenerLock.wakeup();
00289 unlock_(&gListenerLock);
00290 exit_();
00291 }
00292
00293
00294
00295
00296 bool MSNetwork::killListener()
00297 {
00298 MSConnectionHandler *ptr = NULL;
00299
00300 enter_();
00301 lock_(&gListenerLock);
00302 if (gListenerThread && gWaitingToListen > 0) {
00303
00304 lock_(gHandlerList);
00305 ptr = (MSConnectionHandler *) gHandlerList->getBack();
00306 while (ptr) {
00307 if (ptr->amWaitingToListen) {
00308 if (gCurrentTime > ptr->lastUse && (gCurrentTime - ptr->lastUse) > MS_IDLE_THREAD_TIMEOUT) {
00309 ptr->myMustQuit = true;
00310 ptr->wakeup();
00311 break;
00312 }
00313 }
00314 ptr = (MSConnectionHandler *) ptr->getNextLink();
00315 }
00316 unlock_(gHandlerList);
00317 }
00318 unlock_(&gListenerLock);
00319 if (ptr) {
00320 ptr->join();
00321 return_(true);
00322 }
00323 return_(false);
00324 }
00325
00326