00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
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
00061
00062
00063
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
00079
00080 LockCommonBase::~LockCommonBase(void)
00081 {
00082 }
00083
00084
00085
00086 #if defined (OSG_USE_PTHREADS)
00087
00088
00089
00090
00091
00092
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
00108
00109 PThreadLockBase::~PThreadLockBase(void)
00110 {
00111 }
00112
00113
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
00129
00130 void PThreadLockBase::shutdown(void)
00131 {
00132 pthread_mutex_destroy(&(_pLowLevelLock));
00133 }
00134
00135
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
00153
00154
00155
00156
00157 #if defined (OSG_USE_SPROC)
00158
00159
00160
00161
00162
00163
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
00187
00188 SprocLockBase::~SprocLockBase(void)
00189 {
00190 }
00191
00192
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
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
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
00298
00299
00300
00301 #if defined (OSG_USE_WINTHREADS)
00302
00303
00304
00305
00306
00307
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
00327
00328 WinThreadLockBase::~WinThreadLockBase(void)
00329 {
00330 }
00331
00332
00333
00334 bool WinThreadLockBase::init(void)
00335 {
00336 #ifdef OSG_WINLOCK_USE_MUTEX
00337 _pMutex = CreateMutex( NULL,
00338 FALSE,
00339 _szName);
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
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
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
00416
00417
00418
00419
00420
00421
00422
00423 MPLockType Lock::_type("OSGLock", "OSGMPBase", &Lock::create);
00424
00425
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
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
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
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
00494
00495 Lock::~Lock(void)
00496 {
00497 ThreadManager::the()->removeLock(this);
00498
00499 shutdown();
00500 }
00501
00502
00503
00504
00505
00506
00507
00508 MPLockPoolType LockPool::_type("OSGLockPool", "OSGMPBase", &LockPool::create);
00509
00510
00511
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
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
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
00571
00572 LockPool::LockPool(const Char8 *szName,
00573 UInt32 uiId ) :
00574 Inherited(szName, uiId)
00575 {
00576 }
00577
00578
00579
00580 LockPool::~LockPool(void)
00581 {
00582 ThreadManager::the()->removeLockPool(this);
00583
00584 shutdown();
00585 }
00586
00587
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
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
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 }