Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

OSGLock.cpp

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002  *                                OpenSG                                     *
00003  *                                                                           *
00004  *                                                                           *
00005  *             Copyright (C) 2000-2002 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 
00039 #include <stdlib.h>
00040 #include <stdio.h>
00041 
00042 #include "OSGConfig.h"
00043 
00044 #include <iostream>
00045 
00046 #include "OSGLock.h"
00047 
00048 #include "OSGLock.h"
00049 
00050 #include "OSGBaseFunctions.h"
00051 
00052 #include "OSGThreadManager.h"
00053 
00054 #include <errno.h>
00055 #include <OSGLog.h>
00056 
00057 OSG_USING_NAMESPACE
00058 
00059 //---------------------------------------------------------------------------
00060 //  Class
00061 //---------------------------------------------------------------------------
00062 
00063 /*--------------------------- Constructors --------------------------------*/
00064 
00065 LockCommonBase::LockCommonBase(void) :
00066      Inherited(NULL),
00067     _uiLockId (0   )
00068 {
00069 }
00070 
00071 LockCommonBase::LockCommonBase(const Char8  *szName,
00072                                      UInt32  uiId  ):
00073      Inherited(szName),
00074     _uiLockId (uiId  )
00075 {
00076 }
00077 
00078 /*---------------------------- Destructor ---------------------------------*/
00079 
00080 LockCommonBase::~LockCommonBase(void)
00081 {
00082 }
00083 
00084 
00085 
00086 #if defined (OSG_USE_PTHREADS)
00087 
00088 //---------------------------------------------------------------------------
00089 //  Class
00090 //---------------------------------------------------------------------------
00091 
00092 /*--------------------------- Constructors --------------------------------*/
00093 
00094 PThreadLockBase::PThreadLockBase(void):
00095      Inherited    (),
00096     _pLowLevelLock()
00097 {
00098 }
00099 
00100 PThreadLockBase::PThreadLockBase(const Char8  *szName,
00101                                        UInt32  uiId  ) :
00102      Inherited    (szName, uiId),
00103     _pLowLevelLock()
00104 {
00105 }
00106 
00107 /*---------------------------- Destructor ---------------------------------*/
00108 
00109 PThreadLockBase::~PThreadLockBase(void)
00110 {
00111 }
00112 
00113 /*--------------------------- Construction --------------------------------*/
00114 
00115 bool PThreadLockBase::init(void)
00116 {
00117     pthread_mutexattr_t lockAttr;
00118 
00119     pthread_mutexattr_init(&lockAttr);
00120 
00121     pthread_mutexattr_settype(&lockAttr, PTHREAD_MUTEX_RECURSIVE);
00122         
00123     pthread_mutex_init(&(_pLowLevelLock), &lockAttr);
00124 
00125     return true;
00126 }
00127 
00128 /*--------------------------- Destruction ---------------------------------*/
00129 
00130 void PThreadLockBase::shutdown(void)
00131 {
00132     pthread_mutex_destroy(&(_pLowLevelLock));
00133 }
00134 
00135 /*------------------------------- Lock ------------------------------------*/
00136 
00137 void PThreadLockBase::aquire(void)
00138 {
00139     pthread_mutex_lock(&(_pLowLevelLock));
00140 }
00141 
00142 void PThreadLockBase::release(void)
00143 {
00144     pthread_mutex_unlock(&(_pLowLevelLock));
00145 }
00146 
00147 bool PThreadLockBase::request(void)
00148 {
00149     return (pthread_mutex_trylock(&(_pLowLevelLock)) != EBUSY);
00150 }
00151 
00152 #endif /* OSG_USE_PTHREADS */
00153 
00154 
00155 
00156 
00157 #if defined (OSG_USE_SPROC)
00158 
00159 //---------------------------------------------------------------------------
00160 //  Class
00161 //---------------------------------------------------------------------------
00162 
00163 /*--------------------------- Constructors --------------------------------*/
00164 
00165 SprocLockBase::SprocLockBase(void):
00166      Inherited    (    ),
00167 #ifdef OSG_SPROC_USE_LOCK
00168     _pLowLevelLock(NULL)
00169 #else
00170     _pLowLevelSema(NULL)
00171 #endif
00172 {
00173 }
00174 
00175 SprocLockBase::SprocLockBase(const Char8  *szName,
00176                                    UInt32  uiId  ):
00177      Inherited    (szName, uiId),
00178 #ifdef OSG_SPROC_USE_LOCK
00179     _pLowLevelLock(NULL        )
00180 #else
00181     _pLowLevelSema(NULL        )
00182 #endif
00183 {
00184 }
00185 
00186 /*---------------------------- Destructor ---------------------------------*/
00187 
00188 SprocLockBase::~SprocLockBase(void)
00189 {
00190 }
00191 
00192 /*--------------------------- Construction --------------------------------*/
00193 
00194 bool SprocLockBase::init(void)
00195 {
00196     ThreadManager *pThreadManager = ThreadManager::the();
00197 
00198     if(pThreadManager == NULL)
00199         return false;
00200 
00201     if(pThreadManager->getArena() == NULL)
00202         return false;
00203 
00204 #ifdef OSG_SPROC_USE_LOCK
00205     _pLowLevelLock = usnewlock(pThreadManager->getArena());
00206 
00207     if(_pLowLevelLock == NULL)
00208         return false;
00209 
00210     usinitlock(_pLowLevelLock);
00211 
00212 #else
00213     _pLowLevelSema = usnewsema(pThreadManager->getArena(), 1);
00214 
00215     if(_pLowLevelSema == NULL)
00216         return false;
00217 
00218     usinitsema(_pLowLevelSema, 1);
00219     usctlsema (_pLowLevelSema, CS_RECURSIVEON, NULL);
00220 #endif
00221 
00222     return true;
00223 }
00224 
00225 /*--------------------------- Destruction ---------------------------------*/
00226 
00227 void SprocLockBase::shutdown(void)
00228 {
00229     ThreadManager *pThreadManager = ThreadManager::the();
00230 
00231     if(pThreadManager == NULL)
00232         return;
00233 
00234     if(pThreadManager->getArena() == NULL)
00235         return;
00236 
00237 #ifdef OSG_SPROC_USE_LOCK
00238     if(_pLowLevelLock != NULL)
00239     {
00240         usfreelock(_pLowLevelLock, pThreadManager->getArena());
00241     
00242         _pLowLevelLock = NULL;
00243     }
00244 #else
00245     if(_pLowLevelSema != NULL)
00246     {
00247         usfreesema(_pLowLevelSema, pThreadManager->getArena());
00248 
00249         _pLowLevelSema = NULL;
00250     }
00251 #endif
00252 
00253 }
00254 
00255 /*------------------------------- Lock ------------------------------------*/
00256 
00257 void SprocLockBase::aquire(void)
00258 {
00259 #ifdef OSG_SPROC_USE_LOCK
00260     if(_pLowLevelLock != NULL)
00261         ussetlock(_pLowLevelLock);
00262 #else
00263     if(_pLowLevelSema != NULL)
00264         uspsema(_pLowLevelSema);
00265 #endif
00266 }
00267 
00268 void SprocLockBase::release(void)
00269 {
00270 #ifdef OSG_SPROC_USE_LOCK
00271     if(_pLowLevelLock != NULL)
00272         usunsetlock(_pLowLevelLock);
00273 #else
00274     if(_pLowLevelSema != NULL)
00275         usvsema(_pLowLevelSema);
00276 #endif
00277 }
00278 
00279 bool SprocLockBase::request(void)
00280 {
00281     bool  returnValue = false;
00282     Int32 rc          = 0;
00283 
00284 #ifdef OSG_SPROC_USE_LOCK
00285     if(_pLowLevelLock != NULL)
00286         rc = uscsetlock(_pLowLevelLock, 0);
00287 #else
00288     if(_pLowLevelSema != NULL)
00289         rc = uscpsema(_pLowLevelSema);
00290 #endif
00291 
00292     returnValue = (rc == 1);
00293 
00294     return returnValue;
00295 }
00296 
00297 #endif /* OSG_USE_SPROC */
00298 
00299 
00300 
00301 #if defined (OSG_USE_WINTHREADS)
00302 
00303 //---------------------------------------------------------------------------
00304 //  Class
00305 //---------------------------------------------------------------------------
00306 
00307 /*--------------------------- Constructors --------------------------------*/
00308 
00309 WinThreadLockBase::WinThreadLockBase(void) :
00310        Inherited(    )
00311 #ifdef OSG_WINLOCK_USE_MUTEX
00312     , _pMutex   (NULL)
00313 #endif
00314 {
00315 }
00316 
00317 WinThreadLockBase::WinThreadLockBase(const Char8  *szName,
00318                                            UInt32  uiId  ) :
00319        Inherited(szName, uiId)
00320 #ifdef OSG_WINLOCK_USE_MUTEX
00321     , _pMutex   (NULL        )
00322 #endif
00323 {
00324 }
00325 
00326 /*---------------------------- Destructor ---------------------------------*/
00327 
00328 WinThreadLockBase::~WinThreadLockBase(void)
00329 {
00330 }
00331 
00332 /*-------------------------- Construction ---------------------------------*/
00333 
00334 bool WinThreadLockBase::init(void)
00335 {
00336 #ifdef OSG_WINLOCK_USE_MUTEX
00337     _pMutex = CreateMutex( NULL,     // no security attributes
00338                            FALSE,    // initially not owned
00339                           _szName);  // name of mutex
00340 
00341     if(_pMutex == NULL)
00342     {
00343         return false;
00344     }
00345 
00346     return true;
00347 #else
00348     InitializeCriticalSection(&_pCriticalSection);
00349 
00350     return true;
00351 #endif
00352 }
00353 
00354 /*-------------------------- Destruction ----------------------------------*/
00355 
00356 void WinThreadLockBase::shutdown(void)
00357 {
00358 #ifdef OSG_WINLOCK_USE_MUTEX
00359     if(_pMutex != NULL)
00360     {
00361         CloseHandle(_pMutex);
00362     }
00363 #else
00364     DeleteCriticalSection(&_pCriticalSection);
00365 #endif
00366 }
00367 
00368 /*------------------------------- Lock ------------------------------------*/
00369 
00370 void WinThreadLockBase::aquire(void)
00371 {
00372 #if defined(OSG_GV_BETA) && defined(OSG_DBG_LCK)
00373     fprintf(stderr, "Lock::aquire %p\n", this);
00374 #endif
00375 
00376 #ifdef OSG_WINLOCK_USE_MUTEX
00377     WaitForSingleObject(_pMutex, INFINITE);
00378 #else
00379     EnterCriticalSection(&_pCriticalSection);
00380 #endif
00381 }
00382 
00383 void WinThreadLockBase::release(void)
00384 {
00385 #if defined(OSG_GV_BETA) && defined(OSG_DBG_LCK)
00386     fprintf(stderr, "Lock::release %p\n", this);
00387 #endif
00388 
00389 #ifdef OSG_WINLOCK_USE_MUTEX
00390     ReleaseMutex(_pMutex);
00391 #else
00392     LeaveCriticalSection(&_pCriticalSection);
00393 #endif
00394 }
00395 
00396 bool WinThreadLockBase::request(void)
00397 {
00398 #ifdef OSG_WINLOCK_USE_MUTEX
00399     DWORD rc;
00400     rc = WaitForSingleObject(_pMutex, 0);
00401 
00402     if(rc == WAIT_OBJECT_0)
00403     {
00404         return true;
00405     }
00406     else
00407     {
00408         return false;
00409     }
00410 #else
00411     return (TryEnterCriticalSection(&_pCriticalSection) != FALSE);
00412 #endif
00413 }
00414 
00415 #endif /* OSG_USE_WINTHREADS */
00416 
00417 
00418 
00419 //---------------------------------------------------------------------------
00420 //  Class
00421 //---------------------------------------------------------------------------
00422 
00423 MPLockType Lock::_type("OSGLock", "OSGMPBase", &Lock::create);
00424 
00425 /*------------------------------- Get -------------------------------------*/
00426 
00427 Lock *Lock::get(const Char8 *szName)
00428 {
00429     return ThreadManager::the()->getLock(szName, "OSGLock");
00430 }
00431 
00432 Lock *Lock::find(const Char8 *szName)
00433 {
00434     return ThreadManager::the()->findLock(szName);
00435 }
00436 
00437 Lock *Lock::create(void)
00438 {
00439     return Lock::get(NULL);
00440 }
00441 
00442 const MPLockType &Lock::getClassType(void)
00443 {
00444     return _type;
00445 }
00446 
00447 /*------------------------------- Lock ------------------------------------*/
00448 
00449 void Lock::aquire(void)
00450 {
00451     Inherited::aquire();
00452 }
00453 
00454 void Lock::release(void)
00455 {
00456     Inherited::release();
00457 }
00458 
00459 bool Lock::request(void)
00460 {
00461     return Inherited::request();
00462 }
00463 
00464 /*------------------------------ Create -----------------------------------*/
00465 
00466 Lock *Lock::create(const Char8 *szName, UInt32 uiId)
00467 {
00468     Lock *returnValue = NULL;
00469 
00470     returnValue = new Lock(szName, uiId);
00471 
00472     if(returnValue->init() == false)
00473     {
00474         delete returnValue;
00475         returnValue = NULL;
00476     }
00477 
00478     return returnValue;
00479 }
00480 
00481 /*--------------------------- Constructors --------------------------------*/
00482 
00483 Lock::Lock(void) :
00484     Inherited()
00485 {
00486 }
00487 
00488 Lock::Lock(const Char8 *szName, UInt32 uiId) :
00489     Inherited(szName, uiId)
00490 {
00491 }
00492 
00493 /*---------------------------- Destructor ---------------------------------*/
00494 
00495 Lock::~Lock(void)
00496 {
00497     ThreadManager::the()->removeLock(this);
00498 
00499     shutdown();
00500 }
00501 
00502 
00503 
00504 //---------------------------------------------------------------------------
00505 //  Class
00506 //---------------------------------------------------------------------------
00507 
00508 MPLockPoolType LockPool::_type("OSGLockPool", "OSGMPBase", &LockPool::create);
00509 
00510 /*-------------------------------------------------------------------------*/
00511 /*                                Get                                      */
00512 
00513 LockPool *LockPool::get(const Char8 *szName)
00514 {
00515     return ThreadManager::the()->getLockPool(szName, "OSGLockPool");
00516 }
00517 
00518 LockPool *LockPool::find(const Char8 *szName)
00519 {
00520     return ThreadManager::the()->findLockPool(szName);
00521 }
00522 
00523 LockPool *LockPool::create(void)
00524 {
00525     return LockPool::get(NULL);
00526 }
00527 
00528 /*------------------------------ Lock -------------------------------------*/
00529 
00530 #ifdef OSG_WIN32_ICL
00531 #pragma warning (disable : 171)
00532 #endif
00533 
00534 void LockPool::aquire(void *keyP)
00535 {
00536     _pLocks[(UInt64(keyP) & uiLockPoolMask) >> 7].aquire();
00537 }
00538 
00539 void LockPool::release(void *keyP)
00540 {
00541     _pLocks[(UInt64(keyP) & uiLockPoolMask) >> 7].release();
00542 }
00543 
00544 bool LockPool::request(void *keyP)
00545 {
00546     return _pLocks[(UInt64(keyP) & uiLockPoolMask) >> 7].request();
00547 }
00548 
00549 #ifdef OSG_WIN32_ICL
00550 #pragma warning (error : 171)
00551 #endif
00552 
00553 /*------------------------------ Create -----------------------------------*/
00554 
00555 LockPool *LockPool::create(const Char8 *szName, UInt32 uiId)
00556 {
00557     LockPool *returnValue = NULL;
00558 
00559     returnValue = new LockPool(szName, uiId);
00560 
00561     if(returnValue->init() == false)
00562     {
00563         delete returnValue;
00564         returnValue = NULL;
00565     }
00566 
00567     return returnValue;
00568 }
00569 
00570 /*--------------------------- Constructors --------------------------------*/
00571 
00572 LockPool::LockPool(const Char8  *szName,
00573                          UInt32  uiId  ) :
00574     Inherited(szName, uiId)
00575 {
00576 }
00577 
00578 /*---------------------------- Destructor ---------------------------------*/
00579 
00580 LockPool::~LockPool(void)
00581 {
00582     ThreadManager::the()->removeLockPool(this);
00583 
00584     shutdown();
00585 }
00586 
00587 /*--------------------------- Construction --------------------------------*/
00588 
00589 bool LockPool::init(void)
00590 {
00591     bool   returnValue = true;
00592     Char8 *pTmp;
00593 
00594     pTmp = new Char8[strlen(_szName) + 6];
00595 
00596     for(UInt32 i = 0; i < uiLockPoolSize; i++)
00597     {
00598 #ifdef OSG_DEBUG_LOCK_STAT
00599         _pLockStats[i] = 0;
00600 #endif
00601         sprintf(pTmp, "%s%u\n", _szName, i);
00602 
00603         stringDup(pTmp, _pLocks[i]._szName);
00604 
00605         returnValue &= _pLocks[i].init();
00606     }
00607 
00608     delete [] pTmp;
00609 
00610     return returnValue;
00611 }
00612 
00613 /*--------------------------- Destruction ---------------------------------*/
00614 
00615 void LockPool::shutdown(void)
00616 {
00617     for(UInt32 i = 0; i < uiLockPoolSize; i++)
00618     {
00619         _pLocks[i].shutdown();
00620     }
00621 }
00622 
00623 
00624 /*-------------------------------------------------------------------------*/
00625 /*                              cvs id's                                   */
00626 
00627 #ifdef __sgi
00628 #pragma set woff 1174
00629 #endif
00630 
00631 #ifdef OSG_LINUX_ICC
00632 #pragma warning( disable : 177 )
00633 #endif
00634 
00635 namespace
00636 {
00637     static Char8 cvsid_cpp[] = "@(#)$Id: $";
00638     static Char8 cvsid_hpp[] = OSGLOCK_HEADER_CVSID;
00639 }

Generated on Thu Aug 25 04:07:09 2005 for OpenSG by  doxygen 1.4.3