Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

phClientListener.cpp

Go to the documentation of this file.
00001 /* ---------------------------------------------------------------------------
00002     Phission : 
00003         Realtime Vision Processing System
00004 
00005     Copyright (C) 2003 Philip D.S. Thoren (pthoren@cs.uml.edu)
00006     University of Massachusetts at Lowell,
00007     Laboratory for Artificial Intelligence and Robotics
00008 
00009     This file is part of Phission.
00010 
00011  ---------------------------------------------------------------------------*/
00012 /* -------------------------------------------------------------------------- *
00013  * phClientListener.cpp: 
00014  *  Thread class handles all the server's responsibilities for listening and
00015  *  accepting connection from clients.
00016  *  The phClientHandler.cpp source contains the code that handles the
00017  *  client.*
00018  * -------------------------------------------------------------------------- */
00019 #include <phission.h>
00020 #include <phClientListener.h>
00021 
00022 /* -------------------------------------------------------------------------- * 
00023  * phClientListener:
00024  * -------------------------------------------------------------------------- */
00025 phClientListener::phClientListener( int controller_id , 
00026                                     int port , 
00027                                     char *host,
00028                                     phLamportSystem *system )
00029 {
00030     phFUNCTION("phClientListener::phClientListener")
00031     int locked = 0;
00032     
00033     phTHIS_LOOSE_LOCK(locked);
00034     
00035     this->m_port            = 0;
00036     this->m_host            = NULL;
00037     this->m_host_size       = 0;
00038     this->m_controller_id   = -1;
00039     this->m_server          = NULL;
00040     this->m_client_count    = 0;
00041 
00042     this->m_threads         = NULL;
00043     this->m_thread_count    = 0;
00044     
00045     this->m_system          = NULL;
00046     
00047     rc = this->setControllerId(controller_id);
00048     rc = this->setPort(port);
00049     rc = this->setHost(host);
00050     rc = this->setSystem(system); 
00051 
00052 error:
00053     
00054     phTHIS_LOOSE_UNLOCK(locked);
00055     
00056     rc = 0;  
00057 }
00058 
00059 /* -------------------------------------------------------------------------- *
00060  * ~phClientListener:
00061  * -------------------------------------------------------------------------- */
00062 phClientListener::~phClientListener()
00063 {
00064     phFUNCTION("phClientListener::~phClientListener")
00065     int locked = 0;
00066 
00067     phTHIS_LOOSE_LOCK(locked);
00068 
00069     rc = this->joinClientThreads();
00070     phPRINT_RC(rc,NULL,"joinClientThreads");
00071     
00072     this->m_client_count    = 0;
00073     this->m_controller_id = -1;
00074     this->m_port = 0;
00075     phDelete(this->m_server);
00076     phFree(this->m_host);
00077 }
00078 
00079 /* -------------------------------------------------------------------------- *
00080  * setPort:
00081  * -------------------------------------------------------------------------- */
00082 int phClientListener::setPort(int port)
00083 {
00084     phFUNCTION("phClientListener::setPort")
00085     int locked = 0;
00086     
00087     phTHIS_LOCK(locked);
00088 
00089     this->m_port = port;
00090     
00091     phTHIS_UNLOCK(locked);
00092 
00093     return phSUCCESS;
00094 error:
00095     phTHIS_ERROR_UNLOCK(locked);
00096 
00097     return phFAIL;
00098 }
00099 
00100 /* -------------------------------------------------------------------------- *
00101  * getPort:
00102  * -------------------------------------------------------------------------- */
00103 int phClientListener::getPort()
00104 {
00105     phFUNCTION("phClientListener::getPort")
00106     int ret_port = 0;
00107     int locked = 0;
00108     
00109     phTHIS_LOCK(locked);
00110 
00111     ret_port = this->m_port;
00112     
00113 error:
00114     phTHIS_ERROR_UNLOCK(locked);
00115 
00116     return ret_port;
00117 }
00118 /* -------------------------------------------------------------------------- *
00119  * setHost:
00120  * -------------------------------------------------------------------------- */
00121 int phClientListener::setHost(char *host)
00122 {
00123     phFUNCTION("phClientListener::setHost")
00124     int locked = 0;
00125     int length = (host != NULL) ? strlen(host) : 0;
00126    
00127     if (length == 0)
00128     {
00129         return phFAIL;
00130     }
00131     
00132     phTHIS_LOCK(locked);
00133 
00134     if (this->m_host == NULL)
00135     {
00136         this->m_host = (char *)phCalloc(length + 25, sizeof(char));
00137         phCHECK_NULLPTR(this->m_host,"phCalloc","phCalloc failed.");
00138         
00139         this->m_host_size = (length + 25) * sizeof(char);
00140     }
00141     else if (((length+1) * sizeof(char)) > this->m_host_size)
00142     {
00143         this->m_host_size = (length + 25) * sizeof(char);
00144         this->m_host = (char *)phRealloc(this->m_host,
00145                                          this->m_host_size);
00146     }
00147     
00148     sprintf(this->m_host,"%s",host);
00149     
00150     phTHIS_UNLOCK(locked);
00151 
00152     return phSUCCESS;
00153 error:
00154     phTHIS_ERROR_UNLOCK(locked);
00155 
00156     return phFAIL;
00157 }
00158 
00159 /* -------------------------------------------------------------------------- *
00160  * getHost:
00161  * -------------------------------------------------------------------------- */
00162 char *phClientListener::getHost()
00163 {
00164     phFUNCTION("phClientListener::getHost")
00165     char *ret_type = 0;
00166     int locked = 0;
00167     
00168     phTHIS_LOCK(locked);
00169 
00170     ret_type = this->m_host;
00171     
00172 error:
00173     phTHIS_ERROR_UNLOCK(locked);
00174 
00175     return ret_type;
00176 }
00177 
00178 /* -------------------------------------------------------------------------- *
00179  * setControllerId:
00180  * -------------------------------------------------------------------------- */
00181 int phClientListener::setControllerId(int controller_id)
00182 {
00183     phFUNCTION("phClientListener::setControllerId")
00184     int locked = 0;
00185     
00186     phTHIS_LOCK(locked);
00187 
00188     this->m_controller_id = controller_id;
00189     
00190     phTHIS_UNLOCK(locked);
00191 
00192     return phSUCCESS;
00193 error:
00194     phTHIS_ERROR_UNLOCK(locked);
00195 
00196     return phFAIL;
00197 }
00198 
00199 /* -------------------------------------------------------------------------- *
00200  * getControllerId:
00201  * -------------------------------------------------------------------------- */
00202 int phClientListener::getControllerId()
00203 {
00204     phFUNCTION("phClientListener::getControllerId")
00205     int ret_id = 0;
00206     int locked = 0;
00207     
00208     phTHIS_LOCK(locked);
00209 
00210     ret_id = this->m_controller_id;
00211     
00212 error:
00213     phTHIS_ERROR_UNLOCK(locked);
00214 
00215     return ret_id;
00216 }
00217 
00218 /* -------------------------------------------------------------------------- *
00219  * setSystem:
00220  * -------------------------------------------------------------------------- */
00221 int phClientListener::setSystem(phLamportSystem *system)
00222 {
00223     phFUNCTION("phClientListener::setSystem")
00224     int locked = 0;
00225     
00226     phTHIS_LOCK(locked);
00227 
00228     this->m_system = system;
00229     
00230     phTHIS_UNLOCK(locked);
00231 
00232     return phSUCCESS;
00233 error:
00234     phTHIS_ERROR_UNLOCK(locked);
00235 
00236     return phFAIL;
00237 }
00238 
00239 /* -------------------------------------------------------------------------- *
00240  * getSystem:
00241  * -------------------------------------------------------------------------- */
00242 phLamportSystem *phClientListener::getSystem()
00243 {
00244     phFUNCTION("phClientListener::")
00245     phLamportSystem *system = 0;
00246     int locked = 0;
00247     
00248     phTHIS_LOCK(locked);
00249 
00250     system = this->m_system;
00251     
00252 error:
00253     phTHIS_ERROR_UNLOCK(locked);
00254 
00255     return system;
00256 }
00257 
00258 /* -------------------------------------------------------------------------- *
00259  * 
00260  * -------------------------------------------------------------------------- */
00261 int phClientListener::joinClientThreads( )
00262 {
00263     phFUNCTION("phClientListener::joinClientThreads")
00264     int locked = 0;
00265     uint32_t i = 0;
00266     
00267     phTHIS_LOCK(locked);
00268 
00269     /* phPROGRESS("\n"); */
00270 
00271     if (this->m_threads != NULL)
00272     {
00273         for (i = 0; i < this->m_thread_count; i++ )
00274         {
00275             /* phPROGRESS("i:%d\n",i); */
00276             rc = this->m_threads[i]->stop();
00277             phPRINT_RC(rc,NULL,"this->threads[i:%u]->stop()",i);
00278 
00279             phDelete(this->m_threads[i]);
00280         }
00281     }
00282     
00283 
00284     phFree(this->m_threads);
00285     this->m_thread_count  = 0;
00286     
00287     phTHIS_UNLOCK(locked);
00288     
00289     return phSUCCESS;
00290     
00291 error:
00292     phTHIS_UNLOCK(locked);
00293     
00294     return phFAIL;
00295 }
00296 
00297 /* -------------------------------------------------------------------------- *
00298  * 
00299  * -------------------------------------------------------------------------- */
00300 int phClientListener::addClientThread( phClientHandler *client )
00301 {
00302     phFUNCTION("phClientListener::addClientThread")
00303     int locked = 0;
00304     
00305     phCHECK_NULLPTR(client,NULL,"Bad parameter: client == NULL");
00306 
00307     phTHIS_LOCK(locked);
00308     
00309     if ((this->m_thread_count == 0) && (this->m_threads == NULL))
00310     {
00311         DEBUG_PRINT("New client thread array...\n");
00312         this->m_threads = (phClientHandler **)phCalloc(1,
00313                                 sizeof(phClientHandler));
00314         phCHECK_NULLPTR(this->m_threads,"phCalloc","phCalloc failed.");
00315 
00316         this->m_thread_count = 1;
00317     }
00318     else
00319     {
00320         DEBUG_PRINT("Increase client thread array...\n");
00321         this->m_thread_count++;
00322         
00323         this->m_threads = (phClientHandler **)phRealloc(this->m_threads,
00324                 this->m_thread_count * sizeof(phClientHandler));
00325         phCHECK_NULLPTR(this->m_threads,"phRealloc","phRealloc failed.");
00326     }
00327 
00328     DEBUG_PRINT("Adding client (thread_count:%u)...\n",
00329              this->m_thread_count );
00330     this->m_threads[(this->m_thread_count - 1)] = client;
00331     
00332     phTHIS_UNLOCK(locked);
00333     
00334     return phSUCCESS;
00335     
00336 error:
00337     phTHIS_UNLOCK(locked);
00338     
00339     return phFAIL;
00340 }
00341 
00342 
00343 /* -------------------------------------------------------------------------- *
00344  * run:
00345  * -------------------------------------------------------------------------- */
00346 int phClientListener::run()
00347 {
00348     phFUNCTION("phClientListener::run")
00349 
00350     phSocket        *client_sock    = NULL;
00351     phClientHandler *client_thread  = NULL;
00352         
00353     /* make sure there is a mutual exclusion system to negotiate with */
00354     phCHECK_NULLPTR(this->m_system,NULL,
00355         "Bad parameter: this->m_system == NULL" );
00356     
00357     /* Allocate the temporary server to listen for a client node */
00358     this->m_server = new phServerSocket();
00359     phCHECK_NULLPTR(this->m_server,"new","new failed to allocate");
00360     
00361     /* Do any setup here */
00362     rc = this->m_server->setPort(this->getPort());
00363     phPRINT_RC(rc,NULL,"server.setPort");
00364     
00365     rc = this->m_server->setBackLog(10);
00366     phPRINT_RC(rc,NULL,"server.setBackLog()");
00367   
00368     /* Start the server socket listening on the port number
00369      * passed to it in the constructor*/
00370     rc =this->m_server->listen();
00371     phCHECK_RC(rc,NULL,"server.listen()");
00372    
00373     /* Set the server thread to be non-blocking */
00374     rc = this->m_server->setBlocking(phNONBLOCK);
00375     phCHECK_RC(rc,NULL,"server.setBlocking(phNONBLOCK)");
00376     
00377     /* run has the lock until here */
00378     rc = this->signal_running();
00379     phCHECK_RC(rc, NULL, "this->signal_running()");
00380     
00381     while (this->isRunning())
00382     {
00383         /* phPROGRESS("port:%d\n",this->m_port); */
00384 
00385         client_sock = this->m_server->accept();
00386         if (this->isRunning() == 0)
00387         {
00388             phDelete(client_sock);
00389             continue;
00390         }
00391         phCONT_NULLPTR(client_sock, "accept",
00392                      "failed to accept client connection\n\n");
00393 
00394         phPROGRESS("Accepted client on port %d\n",this->m_port);
00395         /* Start up a client handler */
00396         if (client_thread == NULL)
00397         {
00398             client_thread = 
00399                 new phClientHandler(this->getControllerId(),
00400                                     client_sock);
00401             phPRINT_NULLPTR(client_thread,"new",
00402                     "new phClientHandler failed.");
00403 
00404             client_thread->setClientId(this->m_client_count++);
00405             
00406             /* Set the client thread's socket to blocking */
00407             rc = client_sock->setBlocking(phBLOCK);
00408             phPRINT_RC(rc,NULL,"client_sock->setBlocking(phBLOCK)");
00409            
00410             /* Set the distributed mututal exclusion agreement system
00411              * for the client */
00412             rc = client_thread->setSystem(this->m_system);
00413             phPRINT_RC(rc,NULL,"client_thread->setSystem(%p) failed",
00414                     this->m_system);
00415             
00416             /* Spawn the thread */
00417             rc = client_thread->start();
00418             phPRINT_RC(rc,NULL,"client_thread->start()");
00419 
00420             rc = this->addClientThread(client_thread);
00421             phPRINT_RC(rc,NULL,"AddClientThread()\n");
00422             
00423             client_sock = NULL;
00424             client_thread = NULL;
00425         }
00426     }   
00427 
00428     rc = this->joinClientThreads();
00429     phPRINT_RC(rc,NULL,"joinClientThreads");
00430 
00431     return this->m_port;
00432     return phSUCCESS;
00433 error:
00434     rc = this->signal_error();
00435     phCHECK_RC(rc, NULL, "this->signal_error()");
00436    
00437     return phFAIL;
00438 }
00439  
00440 /* ------------------------------------------------------------------------- *
00441  * wakeup: 
00442  * ------------------------------------------------------------------------- */
00443 int phClientListener::wakeup()
00444 {
00445     phFUNCTION("phClientListener::wakeup")
00446     int locked = 0;
00447 
00448     /* phTHIS_LOCK(locked); */
00449     
00450     /* phPROGRESS("\n"); */
00451     if (this->m_server != NULL)
00452     {
00453         this->m_server->wakeup();
00454     }
00455     
00456     /* phTHIS_UNLOCK(locked); */
00457     
00458     return phSUCCESS;
00459 error:
00460     phTHIS_ERROR_UNLOCK(locked);
00461     
00462     return phFAIL;
00463 }
00464     
00465 /* ------------------------------------------------------------------------- *
00466  * cleanup:
00467  * ------------------------------------------------------------------------- */
00468 int phClientListener::cleanup()
00469 {
00470     phFUNCTION("phClientListener::cleanup")
00471     int locked = 0;
00472 
00473     phTHIS_LOCK(locked);
00474     
00475     /* phPROGRESS("\n"); */
00476     phDelete(this->m_server);
00477     
00478     phTHIS_UNLOCK(locked);
00479     
00480     return phSUCCESS;
00481 error:
00482     phTHIS_ERROR_UNLOCK(locked);
00483     
00484     return phFAIL;
00485 }
00486     
00487 
00488 /* ------------------------------------------------------------------------- * 
00489  * error:
00490  * ------------------------------------------------------------------------- */
00491 int phClientListener::error()
00492 {
00493     phFUNCTION("phClientListener::error")
00494     int locked = 0;
00495 
00496     phTHIS_LOCK(locked);
00497 
00498     /* phPROGRESS("\n"); */
00499    
00500     phTHIS_UNLOCK(locked);
00501     
00502     return phSUCCESS;
00503 error:
00504     phTHIS_ERROR_UNLOCK(locked);
00505     
00506     return phFAIL;
00507 }
00508 
00509 




Copyright (C) 2002 - 2007 Philip D.S. Thoren ( pthoren@users.sourceforge.net )
University Of Massachusetts at Lowell
Robotics Lab
SourceForge.net Logo

Generated on Sat Jun 16 02:44:05 2007 for phission by  doxygen 1.4.4