RTIA.cc

Go to the documentation of this file.
00001 // ----------------------------------------------------------------------------
00002 // CERTI - HLA RunTime Infrastructure
00003 // Copyright (C) 2002-2005  ONERA
00004 //
00005 // This file is part of CERTI
00006 //
00007 // CERTI is free software ; you can redistribute it and/or modify
00008 // it under the terms of the GNU General Public License as published by
00009 // the Free Software Foundation ; either version 2 of the License, or
00010 // (at your option) any later version.
00011 //
00012 // CERTI is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY ; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00015 // GNU General Public License for more details.
00016 //
00017 // You should have received a copy of the GNU General Public License
00018 // along with this program ; if not, write to the Free Software
00019 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
00020 //
00021 // $Id: RTIA.cc,v 3.25 2009/04/08 10:47:17 approx Exp $
00022 // ----------------------------------------------------------------------------
00023 
00024 #include <config.h>
00025 #include "RTIA.hh"
00026 
00027 #include <assert.h>
00028 #include <math.h>
00029 #include <limits.h>
00030 
00031 namespace certi {
00032 namespace rtia {
00033 
00034 static pdCDebug D("RTIA", "(RTIA) ");
00035 
00036 // Tableau des messages pouvant etre recus du RTIG
00037 
00038 #define MSG_RTIG_MAX 18
00039 
00040 // ----------------------------------------------------------------------------
00042 RTIA::RTIA(int RTIA_port)
00043 {
00044     // No SocketServer is passed to the RootObject.
00045     rootObject = new RootObject(NULL);
00046 
00047     comm   = new Communications(RTIA_port);
00048     queues = new Queues ;
00049     fm     = new FederationManagement(comm,&stat);
00050     om     = new ObjectManagement(comm, fm, rootObject);
00051     owm    = new OwnershipManagement(comm, fm);
00052     dm     = new DeclarationManagement(comm, fm, rootObject);
00053     tm     = new TimeManagement(comm, queues, fm, dm, om, owm);
00054     ddm    = new DataDistribution(rootObject, fm, comm);
00055 
00056     fm->tm     = tm ;
00057     queues->fm = fm ;
00058     queues->dm = dm ;
00059     om->tm     = tm ;
00060 }
00061 
00062 // ----------------------------------------------------------------------------
00063 // RTIA Destructor
00064 RTIA::~RTIA()
00065 {
00066     // BUG: TCP link destroyed ?
00067 
00068      // Remove temporary file (if not yet done)
00069      if ( fm->_FEDid.c_str() != NULL)
00070         {
00071         if ( fm->_FEDid[0] != '\0' )
00072            {
00073            // If RTIA end (abort ?) before join don't remove file if not temporary
00074            // temporary file name begins with _RT ( yes, but...)
00075            if ( fm->_FEDid[0] != '_' || fm->_FEDid[1] != 'R' || fm->_FEDid[2] != 'T')
00076               {
00077                std::cout<<"** W ** I don't remove file "<<fm->_FEDid<<std::endl;
00078               }
00079            else
00080               {
00081               std::cout<<"*** W ** Removing temporary file "<<fm->_FEDid<<" on RTIA stop."<<std::endl;
00082               std::remove(fm->_FEDid.c_str());
00083               }
00084            fm->_FEDid[0] = '\0' ;
00085            }
00086         }
00087      
00088      /* delete objects in reverse order just like generated destructor would have done */
00089     delete ddm ;
00090     delete tm ;
00091     delete dm ;
00092     delete owm ;
00093     delete om ;    
00094     delete fm ;
00095     delete queues ;
00096     delete comm ;    
00097     delete rootObject ;
00098 }
00099 
00100 // ----------------------------------------------------------------------------
00101 // displayStatistics
00102 void
00103 RTIA::displayStatistics()
00104 {
00105     if (stat.display()) {
00106         cout << stat ;
00107     }
00108 }
00109 
00110 // ----------------------------------------------------------------------------
00112 
00115 void
00116 RTIA::execute()
00117 {
00118     Message        *msg_un;
00119     NetworkMessage *msg_tcp_udp;
00120     int n ;
00121 
00122     while (!fm->_fin_execution) {
00123        
00124         /* 
00125          * readMessage call will allocate EITHER a Network Message or a Message 
00126          *   Network Message will come from a virtual constructor call
00127          *   Message will come from a "simple" constructor call
00128          */
00129         msg_un      = NULL;
00130         msg_tcp_udp = NULL;
00131         try {
00132             switch (tm->_tick_state) {
00133               case TimeManagement::NO_TICK:
00134                 /* tick() is not active:
00135                  *   block until RTIA or federate message comes
00136                  */
00137                 comm->readMessage(n, &msg_tcp_udp, &msg_un, NULL);
00138                 break;
00139 
00140               case TimeManagement::TICK_BLOCKING:
00141                 /* blocking tick() waits for an event to come:
00142                  *   block until RTIA or federate message comes, or timeout expires
00143                  */
00144                 if (tm->_tick_timeout != std::numeric_limits<double>::infinity() &&
00145                     tm->_tick_timeout < LONG_MAX) {
00146 
00147                     struct timeval timev;
00148                     timev.tv_sec = int(tm->_tick_timeout);
00149                     timev.tv_usec = int((tm->_tick_timeout-timev.tv_sec)*1000000.0);
00150 
00151                     comm->readMessage(n, &msg_tcp_udp, &msg_un, &timev);
00152                 }
00153                 else
00154                     comm->readMessage(n, &msg_tcp_udp, &msg_un, NULL);
00155                 break;
00156 
00157               case TimeManagement::TICK_CALLBACK:
00158               case TimeManagement::TICK_RETURN:
00159                 /* tick() waits until a federate callback finishes:
00160                  *   block until federate message comes
00161                  *   RTIA messages are queued in a system queue
00162                  */
00163                 comm->readMessage(n, NULL, &msg_un, NULL);
00164                 break;
00165 
00166               default:
00167                 assert(false);
00168             }
00169 
00170             /* timev is undefined after select() */
00171         }
00172         catch (NetworkSignal) {
00173             fm->_fin_execution = true ;
00174             n = 0 ;
00175             delete msg_un ;
00176             delete msg_tcp_udp ;
00177         }
00178 
00179         switch (n) {
00180           case 0:
00181             break ;
00182           case 1:
00183             processNetworkMessage(msg_tcp_udp);
00184             if (tm->_tick_state == TimeManagement::TICK_BLOCKING)
00185                 processOngoingTick();
00186             break ;
00187           case 2:
00188             processFederateRequest(msg_un);
00189             break ;
00190           case 3: // timeout
00191             if (tm->_tick_state == TimeManagement::TICK_BLOCKING) {
00192                 // stop the ongoing tick() operation
00193                 tm->_tick_state = TimeManagement::TICK_RETURN;
00194                 processOngoingTick();
00195             }
00196             break ;
00197           default:
00198             assert(false);
00199         }
00200     }   
00201 }
00202 
00203 }} // namespace certi/rtia
00204 
00205 // $Id: RTIA.cc,v 3.25 2009/04/08 10:47:17 approx Exp $

Generated on Thu Apr 30 15:53:49 2009 for CERTIDeveloperDocumentation by doxygen 1.5.5