OMKPvmNameServer.cxx

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 "OMKPvmNameServer.h"
00019 
00020 #include <cassert>
00021 #include <pvm3.h>
00022 #include "OMKSvmLink.h"
00023 #include "OMKController.h"
00024 #include "OMKPvmSvm.h"
00025 using namespace std ;
00026 using namespace OMK ;
00027 
00028 //#define _DEBUGDISTRIBUTEDNAMESERVER
00029 
00030 PvmNameServer::PvmNameServer ( int mainNameServerSiteId, NameServer & nameServer ) :
00031 NameServer ( nameServer.getCanonicalRepresentation() ),
00032 _mainNameServerSiteId ( mainNameServerSiteId )
00033 {
00034 #ifdef _DEBUGDISTRIBUTEDNAMESERVER
00035   cerr<<"PvmNameServer::PvmNameServer"<<endl;
00036 #endif
00037 
00038   correspondenceContainerType::const_iterator i ;
00039   for ( i = _stringToIdCorrespondenceContainer.begin() ; 
00040         i != _stringToIdCorrespondenceContainer.end();
00041         ++i ) 
00042   {
00043     _idToNamesUsingIdContainer.insert( placeOfNamesContainerType::value_type((*i).second,
00044                                        new list<Name *>(nameServer.getNamesOfId ((*i).second) ) ) ) ;
00045 
00046     assert ( (*_idToNamesUsingIdContainer.find((*i).second)).second->size() == _tableNbInstances[(*i).second] ) ;
00047   }
00048 
00049   //make sure the constructed PvmName server is compatible with the central name server
00050   int oldbufid = pvm_setsbuf ( 0 ) ; //save the current send buffer 
00051 
00052   if ( oldbufid < 0 )
00053   {
00054     cerr<<"PvmNameServer::PvmNameServer: pvm_setsbuf error "<<oldbufid<<endl;
00055     OMASSERT( false ) ;
00056   }
00057 
00058   int bufid = pvm_initsend( PvmSvm::pvmDataEncoding ) ; 
00059 
00060   if ( bufid < 0 )
00061   {
00062     cerr<<"PvmNameServer::PvmNameServer: pvm_initsend error "<<bufid<<endl;
00063     OMASSERT( false ) ;
00064   }
00065 
00066   //pack a timeStamp
00067   long toto = 0 ;
00068   int infot = pvm_pklong ( &toto, 1, 1 ) ;
00069 
00070   //pack the current name server
00071 
00072   long numberOfPairs = _stringToIdCorrespondenceContainer.size() ;
00073   int info = pvm_pklong ( &numberOfPairs, 1, 1 ) ;
00074 
00075   long verifySize = 0 ;
00076   int stringLength ;
00077   for ( correspondenceContainerType::const_iterator i = _stringToIdCorrespondenceContainer.begin() ;
00078     i != _stringToIdCorrespondenceContainer.end() ;
00079     ++i )
00080   {
00081     ++verifySize ;
00082     stringLength = (*i).first.length() + 1 ;
00083     pvm_pkint ( const_cast<int *>( &stringLength ), 1, 1 ) ;
00084     pvm_pkstr ( const_cast<char *>( (*i).first.c_str() ) ) ;
00085     pvm_pklong ( const_cast<long *>( &( (*i).second ) ) , 1, 1 ) ;
00086   }
00087 
00088   assert (verifySize == numberOfPairs ) ;
00089 
00090   if (info < 0 )
00091   {
00092     cerr<<"PvmNameServer::PvmNameServer: pvm_pkstr error "<<info<<endl;
00093     OMASSERT( false ) ;
00094   }
00095 
00096   info = pvm_send (_mainNameServerSiteId, PvmMessage::NameServiceVerifyLocalNameServer ) ;
00097 
00098   if (info < 0 )
00099   {
00100     cerr<<"PvmNameServer::PvmNameServer: pvm_send error "<<info<<endl;
00101     OMASSERT( false ) ;
00102   }
00103 
00104   info = pvm_setsbuf ( oldbufid ) ; //replace the current send buffer
00105 
00106   if (info < 0 )
00107   {
00108     cerr<<"PvmNameServer::PvmNameServer: pvm_setsbuf error "<<info<<endl;
00109     OMASSERT( false ) ;
00110   }
00111 
00112   //save the current receive buffer
00113   oldbufid = pvm_setrbuf ( 0 ) ;
00114 
00115   //wait for the answer
00116   bufid = pvm_recv (_mainNameServerSiteId, PvmMessage::NameServiceVerifyResult ) ;
00117 
00118   if ( bufid < 0 )
00119   {
00120     cerr<<"PvmNameServer::PvmNameServer: pvm_recv error "<<bufid<<endl;
00121     OMASSERT( false ) ;
00122   }
00123 
00124   int numberOfIncompatibilities ;
00125   info = pvm_upkint ( & numberOfIncompatibilities, 1, 1 ) ;
00126 
00127 
00128   if (info < 0 )
00129   {
00130     cerr<<"PvmNameServer::PvmNameServer: pvm_upkint error "<<info<<endl;
00131     OMASSERT( false ) ;
00132   }
00133 
00134   Name::idType oldId ;
00135   Name::idType newId ;
00136   std::map<Name::idType, Name::idType> listOfNeededConversions ;
00137   for ( int i = 0 ; i < numberOfIncompatibilities ; ++ i )
00138   {
00139     info = pvm_upklong ( & oldId, 1, 1 ) ;
00140 
00141     if (info < 0 )
00142     {
00143       cerr<<"PvmNameServer::PvmNameServer: pvm_upklong error "<<info<<endl;
00144       OMASSERT( false ) ;
00145     }
00146 
00147     info = pvm_upklong ( & newId, 1, 1 ) ;      
00148     if (info < 0 )
00149     {
00150       cerr<<"PvmNameServer::PvmNameServer: pvm_upklong error "<<info<<endl;
00151       OMASSERT( false ) ;
00152     }
00153 
00154     listOfNeededConversions[oldId] = newId ;
00155 
00156   }
00157 
00158 
00159   std::map<Name::idType, Name::idType>::iterator  j = listOfNeededConversions.begin() ;
00160   while ( j != listOfNeededConversions.end() )
00161   {
00162     oldId = (*j).first ;
00163     newId = (*j).second ;
00164 
00165     cerr<<"PvmNameServer::PvmNameServer: converting "<<oldId<<" to "<<newId<<endl;
00166 
00167     assert ( oldId < _nextIdentifier ) ;
00168 
00169     if ( newId >= _nextIdentifier )
00170     {
00171       cerr<<"PvmNameServer::PvmNameServer: updating nextIdentifier from "<<_nextIdentifier<<" to "<< newId + 1 <<endl;
00172       _nextIdentifier = newId + 1 ;
00173     }
00174 
00175     //replace the id in the name server warning : newId could be known or unknown from the name server
00176     bool newIdPresent = ( _tableNbInstances.find(newId) != _tableNbInstances.end() ) ;
00177 
00178     // - first take care of the number of references to the string corresponding to each Id
00179     referenceCountingContainerType::iterator oldRefCount = _tableNbInstances.find(oldId) ;
00180     referenceCountingContainerType::iterator newRefCount = _tableNbInstances.find(newId) ;
00181 
00182     int referencesToOldId = (*oldRefCount).second ;
00183     _tableNbInstances.erase ( oldRefCount ) ;
00184 
00185 
00186     if ( newIdPresent )
00187     {
00188       assert ( newRefCount != _tableNbInstances.end() ) ;
00189       int referencesToNewId = (*newRefCount).second ;
00190       _tableNbInstances.erase ( newRefCount ) ;
00191       _tableNbInstances.insert(referenceCountingContainerType::value_type(oldId, referencesToNewId ) ) ;
00192     }
00193 
00194     //    - only insert once the eventual copy has been archived
00195     _tableNbInstances.insert(referenceCountingContainerType::value_type(newId, referencesToOldId ) ) ;
00196 
00197 
00198     // - then take care of the list of Name instances of each Id              
00199     placeOfNamesContainerType::iterator oldNameList = _idToNamesUsingIdContainer.find(oldId) ;
00200     placeOfNamesContainerType::iterator newNameList = _idToNamesUsingIdContainer.find(newId) ;
00201 
00202     list<Name *> * referencesToOldList = (*oldNameList).second ;
00203     _idToNamesUsingIdContainer.erase ( oldNameList ) ;
00204 
00205     if ( newIdPresent )
00206     {
00207       assert ( newNameList != _idToNamesUsingIdContainer.end() ) ;
00208       list<Name *> * referencesToNewList = (*newNameList).second ;
00209       _idToNamesUsingIdContainer.erase ( newNameList ) ;
00210       _idToNamesUsingIdContainer.insert(placeOfNamesContainerType::value_type(oldId, referencesToNewList) ) ;
00211     }
00212 
00213     //    - only insert once the eventual copy has been archived
00214     _idToNamesUsingIdContainer.insert(placeOfNamesContainerType::value_type(newId, referencesToOldList) ) ;
00215 
00216 
00217     // - then take care of the std::string to Id references 
00218     std::string newStringOfNewId ( (*(*_fastStringAccessTable.find(oldId)).second ).first ) ;
00219     _fastStringAccessTable.erase ( _fastStringAccessTable.find ( oldId ) ) ;
00220     _stringToIdCorrespondenceContainer.erase ( _stringToIdCorrespondenceContainer.find (newStringOfNewId) );
00221 
00222     if ( newIdPresent )
00223     {
00224       std::string newStringOfOldId ( (*(*_fastStringAccessTable.find(newId)).second ).first ) ;
00225       _fastStringAccessTable.erase ( _fastStringAccessTable.find ( newId ) ) ;
00226       _stringToIdCorrespondenceContainer.erase ( _stringToIdCorrespondenceContainer.find (newStringOfOldId) );
00227       pair<correspondenceContainerType::iterator,bool> insertRes = _stringToIdCorrespondenceContainer.insert(correspondenceContainerType::value_type(newStringOfOldId, oldId)) ;
00228       _fastStringAccessTable[oldId] = insertRes.first ;
00229     }
00230 
00231     //    - only insert once the eventual copy has been archived
00232     pair<correspondenceContainerType::iterator,bool> res = _stringToIdCorrespondenceContainer.insert(correspondenceContainerType::value_type(newStringOfNewId, newId)) ;
00233     _fastStringAccessTable[newId] = res.first ;
00234 
00235 
00236     //here, newId and oldId have been exchanged in tha data structures, but not in the OMKNames nor in the listOfNeededConversions. Therefore, we will replace the Name containing oldId with OMKNames containing newId, and change the list Ofneeded conversions so that the conversion from newId to anotherId is replaced by a conversion of oldId to anotherId
00237 
00238     // - replace the id in the OMKNames
00239     newNameList = _idToNamesUsingIdContainer.find ( newId ) ;
00240 
00241     assert ( newNameList != _idToNamesUsingIdContainer.end() ) ;
00242     assert ( (*newNameList).second != NULL ) ;
00243     assert ( (*newNameList).second->size() == _tableNbInstances[ newId ] ) ;
00244 
00245     for ( list<Name *>::iterator listIter = (*newNameList).second->begin() ;
00246       listIter != (*newNameList).second->end() ;
00247       ++listIter )
00248     {
00249       changeNamesId (*listIter, oldId, newId) ;
00250     }
00251 
00252     listOfNeededConversions.erase (j) ;
00253 
00254     if ( newIdPresent )
00255     {
00256       // - update the conversion from newId to anotherId by a conversion of oldId to anotherId
00257       std::map<Name::idType, Name::idType>::iterator k = listOfNeededConversions.find ( newId ) ;
00258       assert ( k != listOfNeededConversions.end() ) ;
00259 
00260       Name::idType anotherId = (*k).second ;
00261 
00262       listOfNeededConversions.erase ( k ) ;
00263 
00264       if ( anotherId != oldId )
00265       {
00266         listOfNeededConversions[oldId] = anotherId ;
00267       }
00268 
00269       // - update the Name so that assertions won't fail and for final permutations
00270       newNameList = _idToNamesUsingIdContainer.find ( oldId ) ;
00271       for ( list<Name *>::iterator listIter = (*newNameList).second->begin() ;
00272         listIter != (*newNameList).second->end() ;
00273         ++listIter )
00274       {
00275         changeNamesId (*listIter, newId, oldId) ;
00276       }
00277 
00278       cerr<<"PvmNameServer::PvmNameServer: "<<oldId<<" will now be converted in "<<anotherId<<endl; 
00279     }
00280 
00281     j = listOfNeededConversions.begin() ;
00282   }
00283 
00284   printToStream ( cout, "\n" ) ;
00285 
00286   cerr<<"Done "<<endl;
00287 
00288 
00289   //restore old receive buffer
00290   info = pvm_setrbuf ( oldbufid );
00291   assert (info != PvmBadParam ) ;
00292   assert (info != PvmNoSuchBuf ) ;
00293 
00294 #ifdef _DEBUGDISTRIBUTEDNAMESERVER
00295   cerr<<"PvmNameServer::PvmNameServer done"<<endl;
00296 #endif
00297 
00298 }
00299 
00300 
00301 PvmNameServer::~PvmNameServer () 
00302 {
00303 
00304 } 
00305 
00306 Name::idType
00307 PvmNameServer::getIdentifierAsFrom(const std::string & name, Name::idType * nextId)
00308 {
00309 #ifdef _DEBUGDISTRIBUTEDNAMESERVER
00310   cerr<<"PvmNameServer::getIdentifierAsFrom"<<endl;
00311 #endif    
00312 
00313   correspondenceContainerType::iterator i;
00314   i = _stringToIdCorrespondenceContainer.find( name );
00315 
00316   if (i == _stringToIdCorrespondenceContainer.end()) 
00317   {
00318     //we are going to change the values contained in the NameServer
00319     //lock() ; 
00320 
00321     i = _stringToIdCorrespondenceContainer.find( name ) ; //name might have been added by an other thread
00322 
00323     if (i == _stringToIdCorrespondenceContainer.end() ) //we have to add nom
00324     { 
00325 #ifdef _DEBUGDISTRIBUTEDNAMESERVER
00326       cerr<<"   PvmNameServer::getIdentifierAsFrom ("<<name<<") on central name server"<<endl;
00327 #endif    
00328       //ask the central name server for the id corresponding to nom
00329 
00330       int oldbufid = pvm_setsbuf ( 0 ) ; //save the current send buffer 
00331 
00332       if ( oldbufid < 0 )
00333       {
00334         cerr<<"PvmNameServer::getIdentifierAsFrom: pvm_setsbuf error "<<oldbufid<<endl;
00335         OMASSERT( false ) ;
00336       }
00337 
00338       int bufid = pvm_initsend( PvmSvm::pvmDataEncoding ) ; 
00339 
00340       //pack a timeStamp
00341       long toto = 0 ;
00342       int infot = pvm_pklong ( &toto, 1, 1 ) ;
00343 
00344       if ( bufid < 0 )
00345       {
00346         cerr<<"PvmNameServer::getIdentifierAsFrom: pvm_initsend error "<<bufid<<endl;
00347         OMASSERT( false ) ;
00348       }
00349       int numberOfCaracters = name.length() + 1 ;
00350       int info = pvm_pkint ( &numberOfCaracters , 1, 1 ) ;
00351 
00352       info = pvm_pkstr ( const_cast<char *> (name.c_str()) ) ;
00353 
00354       if (info < 0 )
00355       {
00356         cerr<<"PvmNameServer::getIdentifierAsFrom: pvm_pkstr error "<<info<<endl;
00357         OMASSERT( false ) ;
00358       }
00359 
00360       info = pvm_send (_mainNameServerSiteId, PvmMessage::NameServiceGetId ) ;
00361 
00362       if (info < 0 )
00363       {
00364         cerr<<"PvmNameServer::getIdentifierAsFrom: pvm_send error "<<info<<endl;
00365         OMASSERT( false ) ;
00366       }
00367 
00368       info = pvm_setsbuf ( oldbufid ) ; //replace the current send buffer
00369 
00370       if (info < 0 )
00371       {
00372         cerr<<"PvmNameServer::getIdentifierAsFrom: pvm_setsbuf error "<<info<<endl;
00373         OMASSERT( false ) ;
00374       }
00375 
00376       //save the current receive buffer
00377       oldbufid = pvm_setrbuf ( 0 ) ;
00378 
00379       //wait for the answer
00380       bufid = pvm_recv (_mainNameServerSiteId, PvmMessage::NameServiceReturnId ) ;
00381 
00382       if ( bufid < 0 )
00383       {
00384         cerr<<"PvmNameServer::getIdentifierAsFrom: pvm_recv error "<<bufid<<endl;
00385         OMASSERT( false ) ;
00386       }
00387 
00388       Name::idType requestedId ;
00389       info = pvm_upklong ( & requestedId, 1, 1 ) ;
00390 
00391 #ifdef _DEBUGDISTRIBUTEDNAMESERVER
00392       cerr<<"   got "<<requestedId<<" from the central name server"<<endl;
00393 #endif    
00394       if (info < 0 )
00395       {
00396         cerr<<"PvmNameServer::getIdentifierAsFrom: pvm_upklong error "<<info<<endl;
00397         OMASSERT( false ) ;
00398       }
00399 
00400       //restore old receive buffer
00401       info = pvm_setrbuf ( oldbufid );
00402       assert (info != PvmBadParam ) ;
00403       assert (info != PvmNoSuchBuf ) ;
00404 
00405       pair<correspondenceContainerType::iterator,bool> res = _stringToIdCorrespondenceContainer.insert(correspondenceContainerType::value_type(name,requestedId)) ; 
00406       _fastStringAccessTable[requestedId] = res.first ;
00407 
00408       *nextId = requestedId + 1 ;
00409 
00410       i = res.first ;
00411     }
00412 
00413     //unlock() ;
00414   }
00415 #ifdef _DEBUGDISTRIBUTEDNAMESERVER
00416   cerr<<"PvmNameServer::getIdentifierAsFrom returning "<<(*i).second<<endl;
00417 #endif    
00418   return (*i).second;
00419 }
00420 
00421 const std::string& PvmNameServer::getStringAssociatedTo (Name::idType id) const 
00422 {
00423   if ( _fastStringAccessTable.find(id) == _fastStringAccessTable.end() )
00424   {
00425     return const_cast<PvmNameServer *>(this)->getStringAssociatedToOnCentralServer( id ) ;
00426   }
00427   else 
00428   {
00429     return  (*(*_fastStringAccessTable.find(id)).second).first ;
00430   }
00431 }
00432 
00433 const std::string& PvmNameServer::getStringAssociatedToOnCentralServer (Name::idType id)
00434 {
00435 #ifdef _DEBUGDISTRIBUTEDNAMESERVER
00436   cerr<<"PvmNameServer::getStringAssociatedTo ("<<id<<")"<<endl;
00437 #endif    
00438   if ( _fastStringAccessTable.find(id) == _fastStringAccessTable.end() )
00439   {
00440     //lock () ;
00441 
00442     if ( _fastStringAccessTable.find(id) == _fastStringAccessTable.end() ) 
00443       //the request might have allready been fullfilled
00444     {
00445       //ask the central name server for the string
00446 
00447       int oldbufid = pvm_setsbuf ( 0 ) ; //save the current send buffer 
00448 
00449       if ( oldbufid < 0 )
00450       {
00451         cerr<<"PvmNameServer::getStringAssociatedTo: pvm_setsbuf error "<<oldbufid<<endl;
00452         OMASSERT( false ) ;
00453       }
00454 
00455       int bufid = pvm_initsend( PvmSvm::pvmDataEncoding ) ; 
00456 
00457       //pack a timeStamp
00458       long toto = 0 ;
00459       int infot = pvm_pklong ( &toto, 1, 1 ) ;
00460 
00461       if ( bufid < 0 )
00462       {
00463         cerr<<"PvmNameServer::getStringAssociatedTo: pvm_initsend error "<<bufid<<endl;
00464         OMASSERT( false ) ;
00465       }
00466 
00467       int info = pvm_pklong ( &id, 1, 1 ) ;;
00468 
00469       if (info < 0 )
00470       {
00471         cerr<<"PvmNameServer::getStringAssociatedTo: pvm_pklong error "<<info<<endl;
00472         OMASSERT( false ) ;
00473       }
00474 
00475       info = pvm_send (_mainNameServerSiteId, PvmMessage::NameServiceGetString ) ;
00476 
00477       if (info < 0 )
00478       {
00479         cerr<<"PvmNameServer::getStringAssociatedTo: pvm_send error "<<info<<endl;
00480         OMASSERT( false ) ;
00481       }
00482 
00483       info = pvm_setsbuf ( oldbufid ) ; //replace the current send buffer
00484 
00485       if (info < 0 )
00486       {
00487         cerr<<"PvmNameServer::getStringAssociatedTo: pvm_setsbuf error "<<info<<endl;
00488         OMASSERT( false ) ;
00489       }
00490 
00491       //save the current receive buffer
00492       oldbufid = pvm_setrbuf ( 0 ) ;
00493 
00494       //wait for the answer
00495       bufid = pvm_recv (_mainNameServerSiteId, PvmMessage::NameServiceReturnString ) ;
00496 
00497       if ( bufid < 0 )
00498       {
00499         cerr<<"PvmNameServer::getStringAssociatedTo: pvm_recv error "<<bufid<<endl;
00500         OMASSERT( false ) ;
00501       }
00502 
00503       int bytes, msgtag, tid ;
00504 
00505       info = pvm_bufinfo ( bufid, &bytes, &msgtag, & tid ) ;
00506 
00507       if (info < 0 )
00508       {
00509         cerr<<"PvmNameServer::getStringAssociatedTo: pvm_bufinfo error "<<info<<endl;
00510         OMASSERT( false ) ;
00511       }
00512 
00513       char * resultingString = new char [bytes] ;
00514 
00515       info = pvm_upkstr ( resultingString ) ;
00516 
00517       if (info < 0 )
00518       {
00519         cerr<<"PvmNameServer::getStringAssociatedTo: pvm_upkstr error "<<info<<endl;
00520         OMASSERT( false ) ;
00521       }
00522 
00523       //restore old receive buffer
00524       info = pvm_setrbuf ( oldbufid );
00525       assert (info != PvmBadParam ) ;
00526       assert (info != PvmNoSuchBuf ) ;
00527 
00528       //insert the new pair in the data structures
00529       pair<correspondenceContainerType::iterator,bool> res = _stringToIdCorrespondenceContainer.insert(correspondenceContainerType::value_type( std::string( resultingString ), id)) ; 
00530       _fastStringAccessTable[id] = res.first ;
00531 
00532       if ( id >= _nextIdentifier ) 
00533       {
00534         _nextIdentifier = id + 1 ;
00535       }
00536     }
00537 
00538     //unlock() ;
00539   }
00540 #ifdef _DEBUGDISTRIBUTEDNAMESERVER
00541   cerr<<"PvmNameServer::getStringAssociatedTo ("<<id<<") ="<<(*(*_fastStringAccessTable.find(id)).second).first<<endl;
00542 #endif    
00543   return  (*(*_fastStringAccessTable.find(id)).second).first ;
00544 }
00545 
00546 bool PvmNameServer::includes (const NameServer & otherNameServer ) 
00547 {
00548   return true ;
00549 }
00550 
00551 void PvmNameServer::deleted(Name::idType id, Name * name)
00552 {
00553 }
00554 
00555 void PvmNameServer::created(Name::idType id, Name * )
00556 {
00557 }

logo OpenMask

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

Generated with doxygen by Dimitri van Heesch ,   1997-2007