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

CommFactory.cpp

Go to the documentation of this file.
00001 ////////////////////////////////////////////////////////////////////////////////
00002 /*! \file CommFactory.cpp
00003 *  \brief Defines the classes that know how to set up the comm network.
00004 *  \author $Author: rsharo $
00005 *  \version $Revision: 1.1 $
00006 *  \date    $Date: 2004/04/07 13:45:04 $
00007 *///////////////////////////////////////////////////////////////////////////////
00008 #include "CommFactory.h"
00009 
00010 #include "ace/INET_Addr.h"
00011 #include "ace/Reactor.h"
00012 #include "ace/TP_Reactor.h"
00013 #include "Utils/SystemProperties.h"
00014 
00015 #include "Comm/AddressServer.h"
00016 #include "Comm/MessageServer.h"
00017 
00018 #include <string>
00019 
00020 
00021 PropertyBasedCommFactory::PropertyBasedCommFactory()
00022         : m_pReactor(NULL),
00023           m_pReactorThread(NULL),
00024           m_pAddressClient(NULL),
00025           m_pAddressServer(NULL),
00026           m_pMessageServer(NULL)
00027 {
00028 }
00029 
00030 
00031 
00032 PropertyBasedCommFactory::PropertyBasedCommFactory(SystemProperties &props,
00033                                                                         const char *mySection)
00034         : m_pReactor(NULL),
00035           m_pReactorThread(NULL),
00036           m_pAddressClient(NULL),
00037           m_pAddressServer(NULL),
00038           m_pMessageServer(NULL)
00039 {
00040                 Open(props, mySection);
00041 }
00042 
00043 
00044 
00045 PropertyBasedCommFactory::~PropertyBasedCommFactory()
00046 {
00047         Close();
00048 }
00049 
00050 
00051 
00052 int PropertyBasedCommFactory::Open(SystemProperties &props,
00053                                                                         const char *mySection)
00054 {
00055         //
00056         // If we already have a message server then return -1
00057         // -- we're already open.
00058         if (m_pMessageServer != NULL)
00059         {
00060                 return -1;
00061         }
00062 
00063         //
00064         // The defaults before properties are applied.
00065         u_int                   numReactorThreads               = 2;
00066         std::string             addrServerHost                  = ACE_DEFAULT_MULTICAST_ADDR;
00067         u_int                   addrServerPort                  = ACE_DEFAULT_MULTICAST_PORT;
00068         u_int                   addrServerTimeout               = 0;
00069         bool                    addrServerAutoDetect    = true;
00070         bool                    spawnAddrServer                 = false;
00071         std::string             addrServerIface                 = "";
00072         bool                    addrServerLoopback              = false;
00073         u_int                   addrServerTTL                   = 1;
00074 
00075         SystemProperties::SectionKey_t                  csSection;
00076 
00077         //
00078         // Find the section.
00079         int status = props.GetSectionKey(mySection, csSection);
00080         if (status == -1)
00081         {
00082                 ACE_ERROR((LM_WARNING, "(%N:%l) Section '%s' of system properties is missing. Using defaults.\n",
00083                         mySection));
00084         }
00085         else
00086         {
00087                 std::string tmpString;
00088                 SystemProperties::Valuetype_t vt;
00089                 
00090                 //
00091                 // Try to get the number of reactor threads from the properties.
00092                 if (props.find_value(csSection, "NumReactorThreads",vt) == 0)
00093                 {
00094                         props.GetIntegerEntry(csSection, "NumReactorThreads",
00095                                                                         numReactorThreads);
00096                 }
00097                 
00098                 //
00099                 // Try to retrieve the IP address of the address server from properties.
00100                 if (props.find_value(csSection, "AddrServerHost",vt) == 0)
00101                 {
00102                         if (props.GetStringEntry(csSection, "AddrServerHost", tmpString) == 0
00103                                         && tmpString != "DEFAULT")
00104                         {
00105                                 addrServerHost = tmpString;
00106                         }
00107                 }
00108                 
00109                 //
00110                 // Try to retrieve the port number of the address server from
00111                 // properties.
00112                 if (props.find_value(csSection, "AddrServerPort",vt) == 0)
00113                 {
00114                         if (
00115                                 vt != SystemProperties::STRING
00116                                 || (props.GetStringEntry(csSection, "AddrServerPort", tmpString) == 0
00117                                         && tmpString != "DEFAULT")
00118                                 )
00119                         {
00120                                 props.GetIntegerEntry(csSection, "AddrServerPort", addrServerPort);
00121                         }
00122                 }
00123                 
00124                 //
00125                 // See if the address server auto detect option is specified.
00126                 if (props.find_value(csSection, "AddrServerTimeout",vt) == 0)
00127                 {
00128                         props.GetIntegerEntry(csSection, "AddrServerTimeout",
00129                                                                          addrServerTimeout);
00130                 }
00131 
00132                 //
00133                 // See if the address server auto detect option is specified.
00134                 if (props.find_value(csSection, "AddrServerAutoDetect",vt) == 0)
00135                 {
00136                         props.GetBooleanEntry(csSection, "AddrServerAutoDetect", 
00137                                                                         addrServerAutoDetect);
00138                 }
00139 
00140                 //
00141                 // See if the user specified what to do for an address server.
00142                 if (props.find_value(csSection, "SpawnAddrServer",vt) == 0)
00143                 {
00144                         //
00145                         // See if we should spawn an address server.
00146                         props.GetBooleanEntry(csSection, "SpawnAddrServer", 
00147                                                                         spawnAddrServer);
00148                 }
00149                         
00150                 //
00151                 // If we might spawn an address server, try to get the properties
00152                 // to do so.
00153                 if (spawnAddrServer || addrServerAutoDetect)
00154                 {
00155                         //
00156                         // Check to see if a multicast interface was specified.
00157                         if (props.find_value(csSection, "AddrServerInterface",vt) == 0)
00158                         {
00159                                 props.GetStringEntry(csSection, "AddrServerInterface",
00160                                                                          addrServerIface);
00161                         }
00162                         
00163                         //
00164                         // Check to see if loopback is to be enabled.
00165                         if (props.find_value(csSection, "AddrServerLoopback",vt) == 0)
00166                         {
00167                                 props.GetBooleanEntry(csSection, "AddrServerLoopback",
00168                                                                                  addrServerLoopback);
00169                         }
00170                         
00171                         //
00172                         // Check to see if TTL is to be enabled.
00173                         if (props.find_value(csSection, "AddrServerTTL",vt) == 0)
00174                         {
00175                                 props.GetIntegerEntry(csSection, "AddrServerTTL",
00176                                                                                  addrServerTTL);
00177                         }
00178                 }
00179         }
00180 
00181         //
00182         // Instantiate the thread pool reactor.
00183         m_pReactor = new ACE_Reactor(new ACE_TP_Reactor(), 1);
00184 
00185 
00186         //
00187         // Spawn the reactor's threads.
00188         m_pReactorThread = new ReactorThread(m_pReactor, numReactorThreads);
00189 
00190 
00191         //
00192         // Construct the address server's IP address.
00193         ACE_INET_Addr   aservAddr(addrServerPort, addrServerHost.c_str());
00194 
00195         //
00196         // Instantiate the AddressClient.
00197         m_pAddressClient = new AddressClient(aservAddr);
00198 
00199         //
00200         // If the timeout was specified, then set it.
00201         if (addrServerTimeout != 0)
00202         {
00203                 m_pAddressClient->SetTimeout(ACE_Time_Value(addrServerTimeout));
00204         }
00205 
00206         //
00207         // Register the address client with the reactor.
00208         m_pAddressClient->RegisterWithReactor(*m_pReactor);
00209 
00210 
00211         //
00212         // If auto-detect, then use the address client to ping the address
00213         // server. If not found after 5 pings, then plan to construct an address
00214         // server locally.
00215         if (addrServerAutoDetect)
00216         {
00217                 int status = -1;
00218                 int i;
00219                 for (i = 1; status == -1 && i <= 5; ++i)
00220                 {
00221                         ACE_DEBUG((LM_INFO,
00222                                 "(%N:%l) Addr Server auto detect try %d...\n", i));
00223 
00224                         status = m_pAddressClient->PingServer();
00225 
00226                         if (status == -1)
00227                                 ACE_DEBUG((LM_INFO, "(%N:%l) Addr Server not found.\n", i));
00228                         else
00229                                 ACE_DEBUG((LM_INFO, "(%N:%l) Addr Server found.\n", i));
00230                 }
00231 
00232                 spawnAddrServer = (status == -1);
00233                 
00234                 if (spawnAddrServer)
00235                         ACE_DEBUG((LM_INFO,
00236                                 "(%N:%l) Auto detect didn't find an address server."
00237                                 " Spawning a local one.\n"));           
00238         }
00239 
00240         //
00241         // If the Address Server is to be spawned, do it.
00242         if (spawnAddrServer)
00243         {
00244                 //
00245                 // Construct the address server with or without a specified
00246                 // multicast interface.
00247                 if (addrServerIface == "")
00248                 {
00249                         m_pAddressServer = new AddressServer(aservAddr);
00250                 }
00251                 else
00252                 {
00253                         m_pAddressServer = new AddressServer(aservAddr,
00254                                 addrServerIface.c_str());
00255                 }
00256 
00257                 //
00258                 // Set the multicast loopback state.
00259                 m_pAddressServer->SetLoopbackEnable(addrServerLoopback);
00260 
00261                 //
00262                 // Set the multicast TTL
00263                 m_pAddressServer->SetTimeToLive(addrServerTTL);
00264 
00265                 //
00266                 // Attach the address server to the reactor.
00267                 m_pAddressServer->RegisterWithReactor(*m_pReactor);
00268         }
00269 
00270         //
00271         // Instantiate the message server and give it a pointer
00272         // to the address client.  The factory keeps ownership of
00273         // the address client, however.
00274         m_pMessageServer = new MessageServer(m_pAddressClient, false);
00275 
00276         //
00277         // Attach the message server to the reactor.
00278         m_pMessageServer->RegisterWithReactor(*m_pReactor);
00279 
00280         
00281         //
00282         // Set up the address server callback mechanism. Note that this
00283         // must be done after the reactor's threads are started.
00284         m_pMessageServer->GetAddressClient()->RegisterServerCallback();
00285 
00286         return 0;
00287 }
00288 
00289 
00290 
00291 int PropertyBasedCommFactory::Close()
00292 {
00293         //
00294         // If the message server is already NULL, then
00295         // return -1 -- we're already closed or closing.
00296         if (m_pMessageServer == NULL)
00297         {
00298                 return -1;
00299         }
00300 
00301         //
00302         // If the address server is local, then make reactor deregistrations
00303         // immediate.  This means no attempt will be made to deregister
00304         // notifications or bindings from the address server.  The address
00305         // server is getting destroyed now anyway.
00306         bool immediateShutdown = (m_pAddressServer != NULL);
00307 
00308         //
00309         // Shut down the message server first.
00310         m_pMessageServer->RemoveFromReactor(*m_pReactor, immediateShutdown);
00311         delete m_pMessageServer;
00312         m_pMessageServer = NULL;
00313 
00314         //
00315         // Next, shut down the address client.
00316         m_pAddressClient->RemoveFromReactor(*m_pReactor, immediateShutdown);
00317         delete m_pAddressClient;
00318         m_pAddressClient = NULL;
00319 
00320         //
00321         // Shut down the address server (if any).
00322         if (m_pAddressServer != NULL)
00323         {
00324                 m_pAddressServer->RemoveFromReactor(*m_pReactor);
00325 
00326                 delete m_pAddressServer;
00327                 m_pAddressServer = NULL;
00328         }
00329 
00330         //
00331         // Delete the reactor thread object. This will cause the reactor
00332         // reactor to stop handling events. The destructor won't return until 
00333         // all the threads finish.
00334         delete m_pReactorThread;
00335         m_pReactorThread = NULL;
00336 
00337         //
00338         // Finally, delete the reactor.
00339         delete m_pReactor;
00340         m_pReactor = NULL;
00341 
00342         return 0;
00343 }
00344 

Generated on Wed Sep 5 12:54:18 2007 for DSACSS Operational Code by  doxygen 1.3.9.1