OSGSharedObjectHandler.cpp

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002  *                                OpenSG                                     *
00003  *                                                                           *
00004  *                                                                           *
00005  *             Copyright (C) 2000-2003 by the OpenSG Forum                   *
00006  *                                                                           *
00007  *                            www.opensg.org                                 *
00008  *                                                                           *
00009  *   contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de          *
00010  *                                                                           *
00011 \*---------------------------------------------------------------------------*/
00012 /*---------------------------------------------------------------------------*\
00013  *                                License                                    *
00014  *                                                                           *
00015  * This library is free software; you can redistribute it and/or modify it   *
00016  * under the terms of the GNU Library General Public License as published    *
00017  * by the Free Software Foundation, version 2.                               *
00018  *                                                                           *
00019  * This library is distributed in the hope that it will be useful, but       *
00020  * WITHOUT ANY WARRANTY; without even the implied warranty of                *
00021  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU         *
00022  * Library General Public License for more details.                          *
00023  *                                                                           *
00024  * You should have received a copy of the GNU Library General Public         *
00025  * License along with this library; if not, write to the Free Software       *
00026  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                 *
00027  *                                                                           *
00028 \*---------------------------------------------------------------------------*/
00029 /*---------------------------------------------------------------------------*\
00030  *                                Changes                                    *
00031  *                                                                           *
00032  *                                                                           *
00033  *                                                                           *
00034  *                                                                           *
00035  *                                                                           *
00036  *                                                                           *
00037 \*---------------------------------------------------------------------------*/
00038 
00043 //---------------------------------------------------------------------------
00044 //  Includes
00045 //---------------------------------------------------------------------------
00046 
00047 #include <cstdlib>
00048 #include <cstdio>
00049 
00050 #include "OSGConfig.h"
00051 
00052 #include <iostream>
00053 
00054 #include "OSGSharedObjectHandler.h"
00055 #include "OSGBaseFunctions.h"
00056 #include "OSGFactoryController.h"
00057 #include "OSGLog.h"
00058 
00059 #ifndef WIN32
00060 #include <dlfcn.h>
00061 #endif
00062 
00063 OSG_USING_NAMESPACE
00064 
00065 //---------------------------------------------------------------------------
00066 //  Class
00067 //---------------------------------------------------------------------------
00068 
00069 /***************************************************************************\
00070  *                               Types                                     *
00071 \***************************************************************************/
00072 
00073 /***************************************************************************\
00074  *                           Class variables                               *
00075 \***************************************************************************/
00076 
00077 TChar SharedObject::_szApplicationObjectName[] = OSGT("Application");
00078 
00079 /***************************************************************************\
00080  *                           Class methods                                 *
00081 \***************************************************************************/
00082 
00083 /*-------------------------------------------------------------------------*\
00084  -  private                                                                -
00085 \*-------------------------------------------------------------------------*/
00086 
00087 /*-------------------------------------------------------------------------*\
00088  -  protected                                                              -
00089 \*-------------------------------------------------------------------------*/
00090 
00091 /*-------------------------------------------------------------------------*\
00092  -  public                                                                 -
00093 \*-------------------------------------------------------------------------*/
00094 
00095 /***************************************************************************\
00096  *                           Instance methods                              *
00097 \***************************************************************************/
00098 
00099 /*-------------------------------------------------------------------------*\
00100  -  private                                                                -
00101 \*-------------------------------------------------------------------------*/
00102 
00103 /*-------------------------------------------------------------------------*\
00104  -  protected                                                              -
00105 \*-------------------------------------------------------------------------*/
00106 
00107 /*------------- constructors & destructors --------------------------------*/
00108 
00109 SharedObject::SharedObject(const TChar *szName) :
00110      Inherited(       ),
00111     _szName   (       ),
00112     _pHandle  (NULL   ),
00113     _type     (Invalid)
00114 {
00115     if(szName == NULL)
00116     {
00117         _szName.assign(_szApplicationObjectName);
00118 
00119         _type = Application;
00120     }
00121     else
00122     {
00123         _szName.assign(szName);
00124 
00125         _type = SharedLibrary;
00126     }    
00127     
00128     FINFO(("construct SharedObject %s\n", _szName.c_str()));
00129 }
00130 
00131 SharedObject::~SharedObject(void)
00132 {
00133     FINFO(("destroy SharedObject %s\n", _szName.c_str()));
00134 }
00135 
00136 bool SharedObject::close(void)
00137 {
00138     bool returnValue = false;
00139 
00140     if(_pHandle != NULL)
00141     {
00142 #ifndef WIN32
00143         returnValue = (dlclose(_pHandle) == 0);
00144 #else
00145         returnValue = (FreeLibrary(_pHandle) != 0);
00146 #endif
00147         _pHandle    = NULL;
00148     }
00149 
00150     return returnValue;
00151 }
00152 
00153 /*-------------------------------------------------------------------------*\
00154  -  public                                                                 -
00155 \*-------------------------------------------------------------------------*/
00156 
00157 /*------------------------------ access -----------------------------------*/
00158 
00159 bool SharedObject::open()
00160 {
00161     const TChar *libName = NULL;
00162 
00163     if(_pHandle != NULL)
00164     {
00165         return true;
00166     }
00167 
00168     if(_type == SharedLibrary)
00169     {
00170         libName = _szName.c_str();
00171     }
00172 
00173 #ifndef WIN32
00174 #ifdef OSG_DLOPEN_LAZY
00175     _pHandle = dlopen(libName, RTLD_LAZY);
00176 #else
00177     _pHandle = dlopen(libName, RTLD_NOW);
00178 #endif
00179 
00180     if(_pHandle == NULL)
00181     {
00182         fprintf(stderr, "%s\n", dlerror()); // Why not using log? !!! DR
00183     }
00184 #else
00185     _pHandle = LoadLibrary(libName);
00186 #endif
00187 
00188     return (_pHandle != NULL);
00189 }
00190 
00191 AnonSymbolHandle SharedObject::getSymbol(const TChar *szSymbolName)
00192 {
00193     AnonSymbolHandle returnValue = NULL;
00194 
00195     if(isOpen() == false)
00196     {
00197         if(open() == false)
00198         {
00199             return returnValue;
00200         }
00201     }
00202 
00203     if(_pHandle != NULL && szSymbolName != NULL)
00204     {
00205 #ifndef WIN32
00206         returnValue = dlsym(_pHandle, szSymbolName);
00207 #else
00208         returnValue = (AnonSymbolHandle) GetProcAddress(_pHandle, 
00209                                                          szSymbolName);
00210 #endif
00211     }
00212 
00213 #ifndef WIN32
00214     if(returnValue == NULL)
00215         fprintf(stderr, "%s\n", dlerror()); // Why not using log? !!! DR
00216 #else
00217 #endif
00218 
00219     return returnValue;
00220 }
00221 
00222 bool SharedObject::isOpen(void)
00223 {
00224     return _pHandle != NULL;
00225 }
00226 
00227 bool SharedObject::reOpen(void)
00228 {
00229     close();
00230     
00231     return open();
00232 }
00233 
00234 const tstring &SharedObject::getName(void)
00235 {
00236     return _szName;
00237 }
00238 
00239 const TChar *SharedObject::getCName(void)
00240 {
00241     return _szName.c_str();
00242 }
00243 
00244 void SharedObject::dump(void)
00245 {
00246     FLOG(("\tObject %s | %p\n", _szName.c_str(), _pHandle));
00247 }
00248 
00249 /*---------------------------- properties ---------------------------------*/
00250 
00251 /*-------------------------- your_category---------------------------------*/
00252 
00253 /*-------------------------- assignment -----------------------------------*/
00254 
00255 /*-------------------------- comparison -----------------------------------*/
00256 
00257 
00258 
00259 
00260 
00261 //---------------------------------------------------------------------------
00262 //  Class
00263 //---------------------------------------------------------------------------
00264 
00265 /***************************************************************************\
00266  *                               Types                                     *
00267 \***************************************************************************/
00268 
00269 /***************************************************************************\
00270  *                           Class variables                               *
00271 \***************************************************************************/
00272 
00273 SharedObjectHandlerP SharedObjectHandler::_the = NULL;
00274 
00275 /***************************************************************************\
00276  *                           Class methods                                 *
00277 \***************************************************************************/
00278 
00279 /*-------------------------------------------------------------------------*\
00280  -  private                                                                -
00281 \*-------------------------------------------------------------------------*/
00282 
00283 /*-------------------------------------------------------------------------*\
00284  -  protected                                                              -
00285 \*-------------------------------------------------------------------------*/
00286 
00287 /*-------------------------------------------------------------------------*\
00288  -  public                                                                 -
00289 \*-------------------------------------------------------------------------*/
00290 
00291 SharedObjectHandlerP SharedObjectHandler::the(void)
00292 {
00293     if(_the == NULL)
00294     {
00295         _the = new SharedObjectHandler;
00296     }
00297 
00298     return _the;
00299 }
00300 
00301 /***************************************************************************\
00302  *                           Instance methods                              *
00303 \***************************************************************************/
00304 
00305 /*-------------------------------------------------------------------------*\
00306  -  private                                                                -
00307 \*-------------------------------------------------------------------------*/
00308 
00309 /*-------------------------------------------------------------------------*\
00310  -  protected                                                              -
00311 \*-------------------------------------------------------------------------*/
00312 
00313 /*------------- constructors & destructors --------------------------------*/
00314 
00315 SharedObjectHandler::SharedObjectHandler(void) :
00316     _mSharedObjects(),
00317     _vLoadedNames  ()
00318 {
00319     FDEBUG(("create SharedObjectHandler\n"));
00320 }
00321 
00322 SharedObjectHandler::~SharedObjectHandler(void)
00323 {
00324     FDEBUG(("destroy SharedObjectHandler\n"));
00325 }
00326 
00327 void SharedObjectHandler::terminate(void)
00328 {
00329     FDEBUG(("terminate SharedObjectHandler\n"));
00330 
00331     //this->dump();
00332 
00333     SharedObjectMapIt soIt  = _mSharedObjects.begin();
00334     SharedObjectMapIt soEnd = _mSharedObjects.end  ();
00335 
00336     while(soIt != soEnd)
00337     {
00338         soIt->second->close();
00339 
00340         OSG::subRef(soIt->second);
00341 
00342         ++soIt;
00343     }
00344 
00345     _the = NULL;
00346     delete this;
00347 }
00348 
00349 /*-------------------------------------------------------------------------*\
00350  -  public                                                                 -
00351 \*-------------------------------------------------------------------------*/
00352 
00353 /*------------------------------ access -----------------------------------*/
00354 
00355 SharedObjectP SharedObjectHandler::getSharedObject(
00356     const TChar *szName)
00357 {
00358     SharedObjectP returnValue = NULL;
00359 
00360     returnValue = findSharedObject(szName);
00361 
00362     if(returnValue == NULL)
00363     {
00364         returnValue = new SharedObject(szName);
00365 
00366         returnValue->open        ();
00367 
00368         OSG::addRef(returnValue);
00369 
00370         _mSharedObjects[returnValue->getName()] = returnValue;
00371 
00372         if(GlobalSystemState == Running)
00373         {
00374             FactoryController::the()->initializePendingElements();
00375         }
00376     }
00377 
00378     for(UInt32 i = 0; i < _vLoadedNames.size(); ++i)
00379     {
00380         FLOG(("Pulled in %s\n", _vLoadedNames[i].c_str()));
00381     }
00382 
00383     _vLoadedNames.clear();
00384 
00385     return returnValue;
00386 }
00387 
00388 SharedObjectP SharedObjectHandler::getOSGSharedObject(
00389     const TChar *szName)
00390 {
00391     SharedObjectP returnValue = NULL;
00392 
00393     tstring tmpString; 
00394 
00395 #ifndef WIN32    
00396     tmpString.append(OSGT("lib"));
00397     tmpString.append(szName);
00398     tmpString.append(OSGT(".so"));
00399 #else
00400     tmpString.append(szName);
00401     tmpString.append(OSGT(".dll"));
00402 #endif
00403 
00404     returnValue = getSharedObject(tmpString.c_str());
00405 
00406     return returnValue;
00407 }
00408 
00409 SharedObjectP SharedObjectHandler::findSharedObject(
00410     const TChar *szName) const
00411 {
00412     SharedObjectMapConstIt  mapIt;
00413     SharedObjectP           returnValue  = NULL;
00414     tstring                 szSearchName;
00415 
00416     if(szName != NULL)
00417     {
00418         szSearchName.assign(szName);
00419     }
00420     else
00421     {
00422         szSearchName.assign(SharedObject::_szApplicationObjectName);
00423     }
00424 
00425     mapIt = _mSharedObjects.find(szSearchName);
00426 
00427     if(mapIt != _mSharedObjects.end())
00428     {
00429         returnValue = mapIt->second;
00430     }
00431     
00432     return returnValue;
00433 }
00434 
00435 void SharedObjectHandler::removeSharedObject(const TChar *szName)
00436 {
00437     SharedObjectMapIt  mapIt;
00438     tstring            szSearchName;
00439 
00440     if(szName != NULL)
00441     {
00442         szSearchName.assign(szName);
00443     }
00444     else
00445     {
00446         szSearchName.assign(SharedObject::_szApplicationObjectName);
00447     }
00448 
00449     mapIt = _mSharedObjects.find(szSearchName);
00450 
00451     _mSharedObjects.erase(mapIt);
00452 }
00453 
00454 void SharedObjectHandler::removeSharedObject(SharedObjectP pObject)
00455 {
00456     if(pObject != NULL)
00457     {
00458         removeSharedObject(pObject->getCName());
00459     }
00460 }
00461 
00462 void SharedObjectHandler::registerLoadedObject(const TChar *szName)
00463 {
00464     tstring tmpString;
00465 
00466 #ifndef WIN32    
00467     tmpString.append(OSGT("lib"));
00468     tmpString.append(szName);
00469     tmpString.append(OSGT(".so"));
00470 #else
00471     tmpString.append(szName);
00472     tmpString.append(OSGT(".dll"));
00473 #endif
00474 
00475     _vLoadedNames.push_back(tmpString);
00476 }
00477 
00478 bool SharedObjectHandler::initialize(void)
00479 {
00480     SharedObjectP pAppHandle = getSharedObject(NULL);
00481 
00482     for(UInt32 i = 0; i < _vLoadedNames.size(); ++i)
00483     {
00484         FLOG(("Preloaded %s %p\n", _vLoadedNames[i].c_str(), pAppHandle));
00485 
00486         _mSharedObjects[_vLoadedNames[i]] = pAppHandle;
00487 
00488         OSG::addRef(pAppHandle);
00489     }
00490 
00491     _vLoadedNames.clear();
00492 
00493     return true;
00494 }
00495 
00496 void SharedObjectHandler::dump(void)
00497 {
00498     SharedObjectMapIt soIt  = _mSharedObjects.begin();
00499     SharedObjectMapIt soEnd = _mSharedObjects.end  ();
00500 
00501     while(soIt != soEnd)
00502     {
00503         FLOG(("SharedObjectHandler::dump: %s | %p\n",
00504               soIt->first.c_str(), soIt->second));
00505 
00506         soIt->second->dump();
00507         ++soIt;
00508     }
00509 }