OMKDistributedController.cpp

Go to the documentation of this file.
00001 /*
00002  * This file is part of openMask © INRIA, CNRS, Universite de Rennes 1 1993-2002, thereinafter the Software
00003  * 
00004  * The Software has been developped within the Siames Project. 
00005  * INRIA, the University of Rennes 1 and CNRS jointly hold intellectual property rights
00006  * 
00007  * The Software has been registered with the Agence pour la Protection des
00008  * Programmes (APP) under registration number IDDN.FR.001.510008.00.S.P.2001.000.41200
00009  *
00010  * This file may be distributed under the terms of the Q Public License
00011  * version 1.0 as defined by Trolltech AS of Norway and appearing in the file
00012  * LICENSE.QPL included in the packaging of this file.
00013  *
00014  * Licensees holding valid specific licenses issued by INRIA, CNRS or Université de Rennes 1 
00015  * for the software may use this file in accordance with that specific license 
00016  *
00017  */
00018 #include <OMKDistributedController.h>
00019 
00020 #include <OMKMirrorObjectHandle.h>
00021 #include <OMKObjectDescriptor.h>
00022 
00023 #include <OMKReferenceObjectHandle.h>
00024 #include "OMKSystemEventIdentifier.h"
00025 #include "OMKUnInitialisedAttributeException.h"
00026 #include "OMKCurrentActiveObject.h"
00027 #include "OMKTracer.h"
00028 #include <OMKScheduler.h>
00029 #ifdef _MSC_VER
00030 #include <time.h>
00031 #else
00032 #include <sys/time.h>
00033 #endif
00034 
00035 using namespace std ;
00036 using namespace OMK ;
00037 using namespace OMK::Type ;
00038 
00039 
00040 //------------------------------------------------------------------------------
00041 
00042 DistributedController::DistributedController( ObjectDescriptor & initialObjects, const Date & initialDate ) 
00043   : Controller(initialObjects, initialDate),
00044     _processName (initialObjects.getProcess())
00045 {
00046 }
00047 
00048 //------------------------------------------------------------------------------
00049 
00050 DistributedController::~DistributedController() 
00051 {
00052   purgeMemoryFromOldEvents ( _date + _stepPeriod ) ;
00053 }
00054 
00055 
00056 DuplicatedObjectHandle * DistributedController::createDuplicatedObject( ObjectDescriptor * objectDescription ) 
00057 {
00058   DuplicatedObjectHandle * result = NULL ;
00059 
00060   SimulatedObject * createdObject = createDescribedObject(objectDescription) ;
00061 
00062   if (createdObject == NULL) 
00063     {
00064       cerr<<"DistributedController::createDuplicatedObject: unable to create "<<*objectDescription<<endl;
00065     }
00066   else
00067     {
00068       result = newOMKDuplicatedObjectHandle(*createdObject) ;
00069          
00070       _referenceObjectsMap.addObjectWithIndex (objectDescription->getName(), result);
00071       _duplicatedObjectsMap.addObjectWithIndex (objectDescription->getName(),result);
00072     }
00073   return result ;
00074 }
00075 
00076 //------------------------------------------------------------------------------
00077 SimulatedObject * DistributedController::getPointerToSimulatedObjectNamed (const Name & nom) {
00078    //std::cout << "***** process " << getObjectDescriptor ().getProcess () << " : demande de " << nom << std::endl ;
00079   //in case of dynamic creation of objects
00080   CurrentActiveObject context ( NULL ) ;   
00081   
00082   SimulatedObject * resultat = NULL ;
00083   // On verifie que l'objet est un referentiel
00084   //cerr<<"DistributedController::getPointerToSimulatedObjectNamed("<<nom<<")"<<endl;
00085   if (nom == getName() ) 
00086     {
00087       resultat = this ;
00088     }
00089   else if (_referenceObjectsMap.find (nom) != _referenceObjectsMap.end ()) 
00090     {
00091       // On recupere le referentiel
00092       resultat = & _referenceObjectsMap.getObjectOfIndex (nom)->getSimulatedObject() ;
00093     } 
00094   else 
00095     {
00096       MirrorObjectsContainerType::iterator i = _mirrorObjectsMap.find (nom) ;
00097       if ( i != _mirrorObjectsMap.end ()) 
00098         {
00099           // On recupere le miroir
00100           resultat = & ( i->second->getSimulatedObject() ) ;
00101         } 
00102       else if (_duplicatedObjectsMap.find (nom) != _duplicatedObjectsMap.end()) 
00103         {
00104           //this shouldn't happen, as duplicate objects are also in the referenceObjectMap
00105           cout<<"DistributedController::getPointerToSimulatedObjectNamed : found in _duplicatedObjectsMap: problem"<<endl;
00106           resultat = &_duplicatedObjectsMap.getObjectOfIndex (nom)->getSimulatedObject() ;
00107         }
00108       
00109       else if (_localObjectsMap.find (nom) != _localObjectsMap.end()) 
00110         {
00111           //this shouldn't happen, as Local objects are also in the referenceObjectMap
00112            //cout<<"DistributedController::getPointerToSimulatedObjectNamed : found in _LocalObjectsMap: problem: "<<nom<<endl;
00113           // TDTD : I think local objects are NOT in the referenceObjectMap...
00114           // BEGIN TDTD : pour voir si ça évite d'avoir un miroir : je renvoie NULL, mais ça ne change rien... !!!
00115           resultat = &_localObjectsMap.getObjectOfIndex (nom)->getSimulatedObject() ;
00116           //resultat = NULL ;
00117           // END TDTD
00118         }
00119       
00120       else {
00121         
00122         ObjectDescriptor * objectDescription = _simulationTree.findDescendantNamed (nom) ;
00123         if ( objectDescription != NULL ) 
00124           {
00125             SimulatedObject * obj = createDescribedObject ( objectDescription ) ;
00126             bool isDuplicatedOject = objectDescription->getDistribution() == ObjectDescriptor::DUPLICATED_OBJECT ;
00127             bool isLocalOject = objectDescription->getDistribution() == ObjectDescriptor::LOCAL_OBJECT ;
00128             if( !isDuplicatedOject && !isLocalOject ) 
00129               {
00130                 createMirrorObject ( objectDescription ) ;
00131               }
00132             else if ( isLocalOject )  
00133               {
00134                  // BEGIN TDTD : enlever les locaux des autres processus
00135                  // ici il y a une amélioration notable, mais ce n'est pas encore cela...
00136                  //std::cout << "##### process " << getObjectDescriptor ().getProcess () << " : demande de " << nom << " qui est sur process " << objLoc->getObjectDescriptor ().getProcess () << std::endl ;
00137                  if (obj->getObjectDescriptor ().getProcess () == getObjectDescriptor ().getProcess ()) {
00138                     //std::cout << "~~~~~ process " << getObjectDescriptor ().getProcess () << " : demande de " << nom << " qui est sur process " << objLoc->getObjectDescriptor ().getProcess () << std::endl ;
00139                     _localObjectsMap.addObjectWithIndex (obj->getName(),(LocalObjectHandle *)getObjectHandle() );
00140                  } else {
00141                     obj = NULL ;
00142                  }
00143                  //_localObjectsMap.addObjectWithIndex (obj->getName(),(LocalObjectHandle *)getObjectHandle() );
00144                  // END TDTD
00145               }
00146             else if ( isDuplicatedOject )
00147               {
00148                 DuplicatedObjectHandle * newObjectHandle = createDuplicatedObject ( objectDescription );   
00149                 if ( objectDescription->getFrequency() != computeAdequateFrequency (objectDescription->getFrequency()) )
00150                   
00151                   {
00152                     //the whole scheduling data structure needs recalculating
00153                     computeScheduling ( false ) ;
00154                     //the new object will therefore be scheduled with all the others
00155                     scheduleControlledObjects() ;
00156                   }
00157                 else 
00158                   {
00159                     scheduleObject ( newObjectHandle ) ;
00160                   }
00161                 sendInitialEventsTo ( *newObjectHandle, _date ) ; 
00162                 fireValuedSignal(SystemEventIdentifier::MaskObjectCreated,nom ) ;
00163                 
00164                 //here, nothing is done for creation process coherence. It might be usefull to initialise the object for duplicated objects
00165               }
00166             resultat = obj ;
00167           }
00168       }
00169     }
00170   return resultat ;
00171 }
00172 
00173 void DistributedController::createLocalObject(const ObjectDescriptor & newLObjectDescription, const Name & fathersLName ) 
00174 {
00175 
00176   _localObjectsMap.addObjectWithIndex (newLObjectDescription.getName(),
00177                                        (LocalObjectHandle *)getObjectHandle()  );
00178   
00179   Name noProcess ;
00180   if ( newLObjectDescription.getProcess() == noProcess )
00181     {
00182       ObjectDescriptor modifiableObjectDescription ( newLObjectDescription ) ;
00183       modifiableObjectDescription.setProcess ( _processName ) ;
00184       Controller::createLocalObject( modifiableObjectDescription, fathersLName ) ;
00185     }
00186   else
00187     {
00188       Controller::createLocalObject( newLObjectDescription, fathersLName ) ;
00189     }
00190 }
00191 /************************************/
00192 int DistributedController::getMirrorsNbre() {
00193   int j=0;
00194   for ( MirrorObjectsContainerType::iterator i = _mirrorObjectsMap.begin(); 
00195         i!= _mirrorObjectsMap.end(); 
00196         i++ )
00197     {
00198       j++;
00199     }
00200   return j;
00201 }
00202 /************************************/
00203 bool DistributedController::isAMirror(const Name & name)
00204 {
00205   if (_mirrorObjectsMap.find (name) !=  _mirrorObjectsMap.end ()) 
00206     return true;
00207   return false;
00208   
00209 }
00210 /*************************************/
00211 vector<Name> DistributedController::getMirrorList()
00212 {
00213   _publicMirrorObjectsVector.clear() ;
00214   for ( MirrorObjectsContainerType::iterator i = _mirrorObjectsMap.begin();
00215         i!= _mirrorObjectsMap.end(); 
00216         i++ )
00217     {
00218       _publicMirrorObjectsVector.push_back( i->first) ;
00219     }
00220 
00221   return  _publicMirrorObjectsVector;
00222 }
00225 const ObjectDescriptor & DistributedController::getObjectDescriptorOfObject(const Name & objectName) 
00226 {
00227   //no call to ancestor, because performer will catch the exception thrown in case of problems
00228   if (_simulationTree.findDescendantNamed(objectName) != NULL )
00229     {
00230       return *(_simulationTree.findDescendantNamed(objectName));
00231     }
00232   else 
00233     {
00234       //the object might have just been deleted : look for it in _deletedObjectDescriptors
00235       list <pair <Date, ObjectDescriptor *> >::iterator i = _deletedObjectDescriptors.begin() ;
00236       while ( i != _deletedObjectDescriptors.end() )
00237         {
00238           if (i->second->getName() == objectName )
00239             {
00240               return *i->second ;
00241             }
00242           ++i ;
00243         }
00244       UserException e("UnknownObject :") ; 
00245       e<<objectName ;
00246       throw e ;
00247     }
00248 }
00249 
00250 //------------------------------------------------------------------------------
00251 
00252 void DistributedController::processStartEventOf(ReferenceObjectHandle * objectHandle)
00253 {
00254   try 
00255     {
00256       Controller::processStartEventOf ( objectHandle ) ;
00257       tableDesInitialises.addObjectWithIndex ( objectHandle->getSimulatedObject ().getName (), 
00258                                                objectHandle) ;
00259 #ifdef _DEBUGDISTRIBUTEDINIT
00260       cerr<<"DistributedController::processStartEventOf init of "
00261           << objectHandle->getSimulatedObject ().getName ()
00262           <<" successfull"<<endl;
00263 #endif
00264     }
00265   catch (UnInitialisedAttributeException&) 
00266     {
00267 #ifdef _DEBUGDISTRIBUTEDINIT
00268       cerr<<"DistributedController::processStartEventOf init of "
00269           << objectHandle->getSimulatedObject ().getName ()
00270           <<" failed"<<endl;
00271 #endif
00272       setComputingState (objectHandle, ReferenceObjectHandle::initial ) ;
00273       tableDesNonInitialises.addObjectWithIndex ( objectHandle->getSimulatedObject ().getName () , 
00274                                                   objectHandle) ;
00275     }
00276 }
00277 
00278 
00279 //------------------------------------------------------------------------------
00280 
00281 void DistributedController::dispatchEvent(Event * event) {
00282 #ifdef _DEBUGEVT
00283   cerr<<"DistributedController::dispatchEvent pour "<<event->receiver<<endl;
00284 #endif
00285   NameToPointerMap<ReferenceObjectHandle>::iterator i = _referenceObjectsMap.find(event->receiver);
00286   OMASSERTM(i!=_referenceObjectsMap.end(), "");
00287   (*i).second->receiveEvent( event );
00288 #ifdef _DEBUGEVT
00289   cerr<<"DistributedController::dispatchEvent fin"<<endl;
00290 #endif
00291 } 
00292 
00293 //------------------------------------------------------------------------------
00294 
00295 MirrorObjectHandle * DistributedController::createMirrorObject(ObjectDescriptor * objectDescription) 
00296 {
00297   MirrorObjectHandle * result = NULL ;
00298   SimulatedObject * obj = createDescribedObject( objectDescription ) ;
00299   if ( obj == NULL )
00300     {
00301       cerr<<"Controller::createMirrorObject: unable to create "<<*objectDescription<<endl;
00302     }
00303   else
00304     {
00305       result = newOMKMirrorObjectHandle(*obj) ;
00306                  
00307       _mirrorObjectsMap.insert ( MirrorObjectsContainerType::value_type(objectDescription->getName (), result ) ) ;
00308     }
00309   return result ;   
00310 }
00311 
00312 //------------------------------------------------------------------------------
00314 // void DistributedController::createControlledObjects(const ObjectDescriptor * subTree) 
00315 // {
00316 //   //go through the simulation tree to find all objects that have to be created
00317 //   ObjectDescriptor::SonsContainerType::const_iterator i = subTree->getSons()->begin() ;
00318 //   while ( i != subTree->getSons()->end() )
00319 //     {
00320 //       if ( (*i)->getProcess() == _processName ) 
00321 //      {
00322 //        cerr<<"Creating "<< (*i)->getName() << endl ;
00323 //        //create the object
00324 //        createReferenceObject ( (*i) ) ;
00325 //      }        
00326 //       else 
00327 //      {
00328 //        cerr<<"Not Creating "<< (*i)->getName() 
00329 //            <<" of process "<< (*i)->getProcess()
00330 //            <<endl ;
00331 //      }
00332 //       //create the subTree of that object
00333 //       createControlledObjects ( *i ) ;
00334        
00335 //       ++i ;
00336 //     }
00337 // }
00339 void DistributedController::createControlledObjects(const ObjectDescriptor * subTree) 
00340 {
00341   //go through the simulation tree to find all objects that have to be created
00342   ObjectDescriptor::SonsContainerType::const_iterator i = subTree->getSons()->begin() ;
00343   while ( i != subTree->getSons()->end() )
00344     {
00345       if ( (*i)->getProcess() == _processName ) 
00346         {
00347 #ifdef _DEBUGEXEC
00348           cerr<<"Creating "<< (*i)->getName() << endl ;
00349 #endif
00350           //create the object
00351           createReferenceObject ( (*i) ) ;
00352         }        
00353       else 
00354         {
00355 #ifdef _DEBUGEXEC
00356           cerr<<"Not Creating "<< (*i)->getName() 
00357               <<" of process "<< (*i)->getProcess()
00358               <<endl ;
00359 #endif
00360         }
00361       //create the subTree of that object
00362       createControlledObjects ( *i ) ;
00363       ++i ;
00364     }
00365 }
00369 void DistributedController::processNewObjectDeclaration ( ObjectDescriptor & declaration, const Date & declarationDate )
00370 {
00371   //cerr<<"DistributedController::processNewObjectDeclaration "<<_processName<<" "<<declaration.getProcess()<<endl;
00372   if ( _processName == declaration.getProcess() ) 
00373     {
00374       Controller::processNewObjectDeclaration ( declaration, declarationDate ) ;
00375     }
00376   else
00377     {
00378       map<Name, list <Event *> >::iterator pendingEvents = _pendingEventsList.find( declaration.getName() ) ;
00379       if ( pendingEvents != _pendingEventsList.end() )
00380         {
00381 #ifdef _DEBUGEXEC
00382           cerr<<"Found pending events for "<<declaration.getName()<<endl;
00383 #endif
00384           for ( list <Event *>::iterator pendingEventsListIterator = pendingEvents->second.begin() ;
00385                 pendingEventsListIterator != pendingEvents->second.end() ;
00386                 ++pendingEventsListIterator)
00387             {
00388 #ifdef _DEBUGEXEC
00389               cerr<<"sent "<<**pendingEventsListIterator<< "to "<<declaration.getName()<<endl;
00390 #endif
00391               OMASSERTM ( getPointerToSimulatedObjectNamed(declaration.getName()) != NULL, "" ) ;
00392               getPointerToSimulatedObjectNamed(declaration.getName())->sendEvent(*pendingEventsListIterator) ; 
00393             }
00394           _pendingEventsList.erase ( pendingEvents ) ;
00395         }
00396     }
00397 }
00398 
00399    
00400 bool DistributedController::processEvent ( Event * event ) {
00401    // TDTD pour la mesure du temps de migration
00402    //static struct timeval start_timer, end_timer ;
00403    //static bool beginMigrationNotYetRegistred = true ;
00404    // fin TDTD
00405    bool result=false ;
00406    if ( event->eventId == SystemEventIdentifier::MaskRegisterForSignal ) {
00407       ValuedEvent<RegistrationData> * realEvent = dynamic_cast<ValuedEvent<RegistrationData> *>( event ) ;
00408       OMASSERTM (realEvent != NULL, "" ) ;
00409       
00410       
00411       _controledObjectsSignalsDispatcher.registerForSignal(realEvent->value._sig , 
00412                                                            realEvent->value._registrant , 
00413                                                            realEvent->value._eventId) ;
00414       
00415       result = true ;
00416       
00417       //find out if an allready broadcasted signal should sent to the registrant
00418       for ( list<pair<EventIdentifier, pair <Event *, Date> > >::iterator i = _broadcastedSignals.begin() ;
00419             i != _broadcastedSignals.end() ;
00420             ++i ) {
00421          if ( i->first == realEvent->value._sig ) {
00422             if ( i->second.second >= realEvent->date ) {
00423                Event * sentEvent = i->second.first->clone() ;
00424                sentEvent->eventId = realEvent->value._eventId ;
00425                sentEvent->receiver = realEvent->value._registrant ;
00426                sendEvent ( sentEvent ) ;
00427             }
00428          }
00429       }
00430    } else if ( event->eventId == SystemEventIdentifier::MaskCancelRegistrationForSignal ) {
00431       ValuedEvent<CancellationData> * realEvent = dynamic_cast<ValuedEvent<CancellationData> *>( event ) ;
00432 
00433       OMASSERTM (realEvent != NULL, "" ) ;
00434 
00435       _controledObjectsSignalsDispatcher.cancelRegistrationForSignal (realEvent->value._sigId , 
00436                                                                       realEvent->value._registrant) ;
00437       result = true ;
00438    } else if (event->eventId == SystemEventIdentifier::MaskObjectDestroyed) {
00439       ValuedEvent<Name> * realEvent = dynamic_cast<ValuedEvent<Name> *>( event ) ;
00440 
00441       OMASSERTM ( realEvent != NULL, "" ) ;
00442 
00443       ObjectDescriptor * objectDescriptor = _simulationTree.findDescendantNamed ( realEvent->value ) ;
00444 
00445       if (objectDescriptor != NULL ) {
00446          deleteObject( objectDescriptor ) ;
00447       }
00448       result = Controller::processEvent ( event ) ;
00449    }
00451    else if ( event->eventId == SystemEventIdentifier::MaskNewLocalObject ) 
00452    {
00453       CreateObjectEvent * creationEvent = dynamic_cast< CreateObjectEvent* > ( event ) ;
00454          
00455       OMASSERTM (creationEvent != NULL, "" ) ;
00456       result = true ; // TDTD ajout ...
00457       // add the described object in the simulation tree : this is a declaration
00458       ObjectDescriptor * objectDescriptor = 
00459         _simulationTree.findDescendantNamed( creationEvent->value.getValue().first.getName() );
00460       if ( objectDescriptor == NULL ) {
00461          if ( (creationEvent->value.getValue().first.getProcess())==
00462               (getObjectDescriptor().getProcess()) ) {
00463             ObjectDescriptor * newObjectDescriptor = 
00464                new ObjectDescriptor(creationEvent->value.getValue().first) ;
00465               
00466             ObjectDescriptor * fathersDescription = 
00467                _simulationTree.findDescendantNamed ( creationEvent->value.getValue().second ) ;
00468               
00469             if (fathersDescription == NULL) {
00470                fathersDescription = & _simulationTree ;
00472                   //              ostringstream warningMessage ;
00473                   //              warningMessage<<"Attached new object named "
00474                   //                            <<newObjectDescriptor->getName()<<" to "<<getName()
00475                   //                            <<" because object "<<creationEvent->value.getValue().second
00476                   //                            <<"is unknown"<<endl;
00477                   //              warning ( warningMessage.str() , SomeWarnings ) ;
00479             }
00480             changeObjectsFather (newObjectDescriptor, fathersDescription) ;
00481               
00482             //create the described object
00483             processNewObjectDeclaration ( *newObjectDescriptor, event->date ) ;
00484               
00485             // notify other objects that an object has been created
00486             fireValuedSignal( SystemEventIdentifier::MaskObjectCreated,
00487                               creationEvent->value.getValue().first.getName() ) ;
00488          }
00489       } else {
00491           //      ostringstream warningMessage ;
00492           //      warningMessage<<"WARNING: an object of name "
00493           //                    <<creationEvent->value.getValue().first.getName()<<" already exists"<<endl;
00494           //      warning ( warningMessage.str() , SomeWarnings ) ;
00496       }
00497    } else if ( event->eventId == SystemEventIdentifier::MaskMetamorphoseMirToRef ) {
00498       //------- gestion de la migration (chadi)
00499 //       if (beginMigrationNotYetRegistred) { // TDTD pour la mesure du temps de migration
00500 //       gettimeofday(&start_timer, NULL);
00501 //       //std::cerr << "temps de début pris à la date " << getSimulatedDate () << std::endl ;
00502 //       beginMigrationNotYetRegistred = false ;
00503 //       }
00504       MigrationObjectEvent * morphoseEvent = dynamic_cast< MigrationObjectEvent* > ( event ) ;
00505        
00506       OMASSERTM (morphoseEvent != NULL, "" ) ;
00507       result = true ; // TDTD ajout ...
00508        
00509       Name objectToMigrate = morphoseEvent->value.getValue().first ;
00510       Name destinationProcess = morphoseEvent->value.getValue().second ;
00511       exProcessName = getObjectDescriptorOfObject(objectToMigrate).getProcess();
00512       
00513       if (! (getObjectDescriptorOfObject(objectToMigrate).getProcess () == destinationProcess)) {
00514          //si egale ca veut dire ke le ref est deja 
00515          //sur le site destination, donc rien a faire ...
00516          //appeler emigrate() pour sauvegarder les valeurs internes de l'objet
00517          // getPointerToSimulatedObjectNamed(objectToMigrate)->emigrate() ;
00518          
00519          if (destinationProcess == _processName) {
00520             // ca veut dire ke g localise le site detenant le miroir elu pr etre ref
00521             MirrorObjectsContainerType::iterator i = 
00522                _mirrorObjectsMap.find (objectToMigrate) ;
00523             if (i != _mirrorObjectsMap.end ()) {                   
00524                MirrorObjectHandle * mirObjHandle =  i->second ;
00525                SimulatedObject * objectPtr = &(i->second->getSimulatedObject ()) ;
00526                mirObjHandle->cancelRegistrationToReferenceObject () ;
00527                mirObjHandle->setMorphosisPhaseTrue () ;
00528                
00529                deleteObjectHandle (mirObjHandle) ;
00530                
00531                ReferenceObjectHandle * refObjHandle = createReferenceObjectHandle (*objectPtr) ;
00532                _referenceObjectsMap.addObjectWithIndex (objectToMigrate, refObjHandle) ;
00533                _mirrorObjectsMap.erase (i) ;
00534                
00535                processStartEventAfterMorphose (refObjHandle) ;
00536                tableDesInitialises.addObjectWithIndex (refObjHandle->getSimulatedObject ().getName (), 
00537                                                        refObjHandle) ;
00538                scheduleObject (refObjHandle) ;
00539                
00540                ObjectDescriptor * descriptorOfObjectToMigrate = 
00541                   const_cast<ObjectDescriptor *> (&getObjectDescriptorOfObject (objectToMigrate)) ;
00542                descriptorOfObjectToMigrate->setProcess (destinationProcess) ;
00543                
00544                //maintenant il faut envoyer un event pour alerter les miroirs:
00545                //a la reception de cet event les miroirs doivent se deshabonner de 
00546                //l'ex ref et s'abonner au nouveau
00547                
00548         MigrationObjectEvent linkToNewRefEvent( 
00549           SystemEventIdentifier::MaskLinkToNewReferential,
00550           getSimulatedDate (),
00551           getName (),
00552           getName (),
00553           MigrationObjectType( MigrationObjectPrm( objectToMigrate, destinationProcess ) ) ) ;
00554                
00555                sendEvent (linkToNewRefEvent) ;
00556             }
00557          } else { //dans ce cas que les autres miroirs se desabonnent de leur ex-ref
00558             MirrorObjectsContainerType::iterator i = _mirrorObjectsMap.find (objectToMigrate) ;
00559             if (i != _mirrorObjectsMap.end ())  {
00560                ObjectDescriptor * descriptorOfObjectToMigrate = 
00561                   const_cast<ObjectDescriptor *>
00562                   (&getObjectDescriptorOfObject (objectToMigrate)) ;
00563                descriptorOfObjectToMigrate->setProcess (destinationProcess) ;
00564                
00565                MirrorObjectHandle * moh =  (i->second) ;
00566                moh->cancelRegistrationToReferenceObject () ;
00567                moh->setMorphosisPhaseTrue () ;
00568             }
00569             // TDTD j'enlève les commentaires pour faire fonctionner la migration, en modifiant un peu...
00570             if (_referenceObjectsMap.find (objectToMigrate) != _referenceObjectsMap.end ()) {
00571                SimulatedObject * objectPtr =
00572                   &_referenceObjectsMap.getObjectOfIndex (objectToMigrate)->getSimulatedObject() ; 
00573                objectPtr->emigrate () ;
00574                ReferenceObjectHandle * refer =  
00575                   dynamic_cast<ReferenceObjectHandle* >
00576                   (_referenceObjectsMap.getObjectOfIndex(objectToMigrate));
00577                refer->setMorphosisPhaseTrue () ;
00578             }
00579          }
00580       }
00581    }
00582    else if (event->eventId == SystemEventIdentifier::MaskLinkToNewReferential)
00583    {
00584       MigrationObjectEvent * changeRefEvent = dynamic_cast< MigrationObjectEvent* >( event ) ;
00585 
00586       OMASSERTM (changeRefEvent != NULL, "" ) ;
00587       result = true ; // TDTD ajout ...
00588       Name objectToMigrate = changeRefEvent->value.getValue().first ;
00589       Name destinationProcess = changeRefEvent->value.getValue().second ;
00590       
00591       if (_processName != destinationProcess) 
00592       {
00593                if (_processName!=exProcessName) 
00594          {
00595                   //donc c'est un site ki a un miroir, alors brancher ce miroir
00596                   //sur son nouveau Ref
00597                   MirrorObjectsContainerType::iterator i = _mirrorObjectsMap.find (objectToMigrate) ;
00598                   MirrorObjectHandle * moh = (i->second) ;
00599                   moh->linkToNewReferential(destinationProcess) ;
00600                } 
00601          else 
00602          {
00603                   //donc c le site ki a l'ex-ref il faut le transformer
00604                   //en miroir et le brancher sur le nouveau ref
00605                   MirrorObjectHandle * miroir = NULL ;
00606                   ReferenceObjectHandle * refe = _referenceObjectsMap.getObjectOfIndex (objectToMigrate) ;
00607                   SimulatedObject * objectPtr =  
00608                      &_referenceObjectsMap.getObjectOfIndex (objectToMigrate)
00609                      ->getSimulatedObject () ;      
00610                   ObjectDescriptor * descriptorOfObjectToMigrate = 
00611                      const_cast<ObjectDescriptor *>
00612                      (& _referenceObjectsMap.getObjectOfIndex (objectToMigrate)
00613                       ->getSimulatedObject ().getObjectDescriptor ()) ;
00614                   descriptorOfObjectToMigrate->setProcess (destinationProcess) ;
00615                   refe->setMigrationCaseToTrue () ;
00616                   _scheduler->unschedule (refe) ;
00617                   _scheduler->removeFromScheduable (refe) ;
00618                   _referenceObjectsMap.erase (objectToMigrate) ;
00619                   deleteObjectHandle (refe) ;
00620                   miroir = newOMKMirrorObjectHandle (*objectPtr) ;
00621                   _mirrorObjectsMap.insert 
00622                      (MirrorObjectsContainerType::value_type (objectPtr->getName (), miroir)) ;
00623                   miroir->linkToNewReferential (destinationProcess) ;
00624                }
00625                //gettimeofday (&end_timer, NULL) ;
00626       }
00627    } else if (event->eventId == "MaskSaveInternalValue") {
00628       result = true ; // TDTD ajout ...
00629       if (_referenceObjectsMap.find (event->sender) != _referenceObjectsMap.end ()) {
00630          SimulatedObject * objectPtr =  
00631             &_referenceObjectsMap.getObjectOfIndex (event->sender)->getSimulatedObject () ; 
00632          objectPtr->immigrate (event) ;
00633       } else if (_mirrorObjectsMap.find (event->sender) != _mirrorObjectsMap.end ()) {
00634          MirrorObjectsContainerType::iterator i = _mirrorObjectsMap.find (event->sender) ;
00635          SimulatedObject * objectPtr = &(i->second->getSimulatedObject ()) ;
00636          objectPtr->immigrate (event) ;
00637       }
00638       //gettimeofday (&end_timer, NULL) ;
00640    // TDTD ajout pour mesurer le temps
00641 //    } else if (event->eventId == "PrintMigrationDuration") {
00642 //       result = true ;
00643 //       double time_in_ms = (end_timer.tv_sec - start_timer.tv_sec) * 1000.0 +
00644 //       (end_timer.tv_usec - start_timer.tv_usec) / 1000.0 ;
00645 //       std::cout << "migration duration on process " << _processName << " = " << time_in_ms << std::endl ;
00646 //       beginMigrationNotYetRegistred = true ;
00647    } else {
00648       result = Controller::processEvent ( event ) ;
00649    }
00650    return result ;
00651 }
00652  
00653 
00654 
00655 void DistributedController::deleteObject ( ObjectDescriptor * objectDescriptor )
00656 {
00657   _deletedObjectDescriptors.push_back ( make_pair ( _date,objectDescriptor ) ) ;
00658   Controller::deleteObject ( objectDescriptor ) ;
00659 }
00660 
00661 
00662 
00663 void DistributedController::createObject(const ObjectDescriptor & newObjectDescription,
00664                                            const Name & fathersName)
00665 {
00666   Name noProcess ;
00667   if ( newObjectDescription.getProcess() == noProcess )
00668     {
00669       ObjectDescriptor modifiableObjectDescription ( newObjectDescription ) ;
00670       modifiableObjectDescription.setProcess ( _processName ) ;
00671       Controller::createObject( modifiableObjectDescription, fathersName ) ;
00672     }
00673   else
00674     {
00675       Controller::createObject( newObjectDescription, fathersName ) ;
00676     }
00677 }
00678 
00679 void DistributedController::purgeMemoryFromOldEvents ( const Date & dateOfOldestKept )
00680 {
00681   // purge object descriptors first
00682   bool disposableElements = !_deletedObjectDescriptors.empty() ;
00683   pair <Date, ObjectDescriptor *> examinedObjectDescriptor ;
00684   while ( disposableElements )
00685     {
00686       examinedObjectDescriptor = _deletedObjectDescriptors.front() ;
00687       if ( examinedObjectDescriptor.first < dateOfOldestKept )
00688         {
00689 #ifdef _DEBUGEXEC
00690           cerr<<"DistributedController::purgeMemoryFromOldEvents: deleting "
00691               <<examinedObjectDescriptor.second->getName()<<endl;
00692 #endif
00693           //only delete if it will not be deleted by the ancestor class : no object (nor object handle) was created
00694           if (  examinedObjectDescriptor.second->getProcess() != _processName )
00695             {
00696                      
00697               //if ( ) delete examinedObjectDescriptor.second ;
00698             }
00699           _deletedObjectDescriptors.pop_front() ;
00700           disposableElements = !_deletedObjectDescriptors.empty() ;
00701         }
00702       else 
00703         {
00704           disposableElements = false ;
00705         }
00706     }
00707    
00708 
00709 
00710 
00711   Controller::purgeMemoryFromOldEvents ( dateOfOldestKept ) ;
00712   //purge the list of old broadcasted signals. 2 * _stepPeriod is arbitrary. The effective distributed controller should redefine this according to it's latency
00713   pair<EventIdentifier, pair <Event *, Date> > examinedPair ;
00714   disposableElements = !_broadcastedSignals.empty() ;
00715   while ( disposableElements )
00716     {
00717       examinedPair = _broadcastedSignals.front() ;
00718       if ( examinedPair.second.second < dateOfOldestKept )
00719         {
00720           delete examinedPair.second.first ;
00721           _broadcastedSignals.pop_front() ;
00722           disposableElements = !_broadcastedSignals.empty() ;
00723         }
00724       else 
00725         {
00726           disposableElements = false ;
00727         }
00728     }
00729    
00730 }
00731 
00732 void DistributedController::broadcastEventsForSignal ( Event & event, const EventIdentifier & sigId )
00733 {
00734   Controller::broadcastEventsForSignal ( event, sigId ) ;
00735 
00736   //remember the broadcasted signal to be able to send it to objects whose registration is still under way
00737   _broadcastedSignals.push_back ( make_pair ( sigId, make_pair (event.clone(), _date) ) ) ;
00738 
00739 }
00740 
00741 bool DistributedController::receiveRegistrationForSignal(const EventIdentifier & sig,
00742                                                            const Name & registrant, 
00743                                                            const EventIdentifier & eventId)
00744 {
00745   //   cerr << "DistributedController::receiveRegistrationForSignal " << sig << " | " << registrant << " | " << eventId << endl ;
00746   ValuedEvent<RegistrationData> * event ;
00747   event= new ValuedEvent<RegistrationData> (SystemEventIdentifier::MaskRegisterForSignal, _date, getName(), getName() ,RegistrationData (sig, registrant, eventId) ) ;
00748   sendEvent (event) ;
00749   return true ;
00750 }
00751 
00752 
00753 bool DistributedController::receiveCancellationForSignal ( const EventIdentifier & sigId , const Name & registrant ) {
00754   ValuedEvent<CancellationData> * event ;
00755   event= new ValuedEvent<CancellationData> (SystemEventIdentifier::MaskCancelRegistrationForSignal, _date, getName(), getName() ,CancellationData (sigId, registrant) ) ;
00756   sendEvent (event) ;
00757   return true ;
00758 }
00759 
00760 DistributedController::RegistrationData::RegistrationData (const EventIdentifier & sig,
00761                                                              const Name & registrant, 
00762                                                              const EventIdentifier & eventId) :
00763   _sig ( sig ),
00764   _registrant (registrant),
00765   _eventId (eventId)
00766 {
00767 }
00768 
00769 DistributedController::RegistrationData::~RegistrationData ()
00770 {
00771 }
00772 void DistributedController::RegistrationData::unpack (IncomingSynchronisationMessage & in ) 
00773 {
00774   in>>_sig>>_registrant>>_eventId ;  
00775 }
00776 
00777 void DistributedController::RegistrationData::pack (OutgoingSynchronisationMessage & out) const 
00778 {
00779   out<<_sig<<_registrant<<_eventId;
00780 }
00781 
00782 void DistributedController::RegistrationData::extract (istream & in ) 
00783 {
00784   in>>_sig>>_registrant>>_eventId ;  
00785 }
00786 
00787 void DistributedController::RegistrationData::insertInStream (ostream &  out) const 
00788 {
00789   out<<_sig<<" "<<_registrant<<" "<<_eventId<<" ";
00790 }
00791 
00792 
00793 
00794 PolatorNT * DistributedController::RegistrationData::createPolator() 
00795 {
00796   return new Polator<RegistrationData>() ;
00797 }
00798 PolatorNT * DistributedController::CancellationData::createPolator() 
00799 {
00800   return new Polator<CancellationData>() ;
00801 }
00802 DistributedController::CancellationData::CancellationData (const EventIdentifier & sigId,
00803                                                              const Name & registrant ) :
00804   _sigId ( sigId ),
00805   _registrant (registrant)
00806 {
00807 }
00808 
00809 DistributedController::CancellationData::~CancellationData ()
00810 {
00811 }
00812 void DistributedController::CancellationData::unpack (IncomingSynchronisationMessage & in ) 
00813 {
00814   in>>_sigId>>_registrant;  
00815 }
00816 
00817 void DistributedController::CancellationData::pack (OutgoingSynchronisationMessage & out) const 
00818 {
00819   out<<_sigId<<_registrant;
00820 }
00821 
00822 void DistributedController::CancellationData::extract (istream & in ) 
00823 {
00824   in>>_sigId>>_registrant;  
00825 }
00826 
00827 void DistributedController::CancellationData::insertInStream (ostream &  out) const 
00828 {
00829   out<<_sigId<<" "<<_registrant<<" ";
00830 }
00831 

logo OpenMask

Documentation generated on Mon Jun 9 11:45:56 2008

Generated with doxygen by Dimitri van Heesch ,   1997-2007