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 }
Documentation generated on Mon Jun 9 11:45:57 2008 |
Generated with doxygen by Dimitri van Heesch , 1997-2007 |