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 #ifdef OSG_DOC_FILES_IN_MODULE
00040
00043 #endif
00044
00045 #include <stdlib.h>
00046 #include <stdio.h>
00047
00048 #include "OSGConfig.h"
00049
00050 #include <iostream>
00051
00052 #include "OSGThread.h"
00053 #include "OSGBaseFunctions.h"
00054 #include "OSGChangeList.h"
00055 #include "OSGThreadManager.h"
00056 #include "OSGLog.h"
00057
00058 #if ! defined (OSG_USE_PTHREADS) && ! defined (OSG_USE_WINTHREADS)
00059 #include <sys/types.h>
00060 #include <sys/prctl.h>
00061 #include <errno.h>
00062
00063 #include <sys/types.h>
00064 #include <sys/wait.h>
00065 #include <unistd.h>
00066 #include <signal.h>
00067 #endif
00068
00069 OSG_USING_NAMESPACE
00070
00071 const UInt32 ThreadCommonBase::InvalidAspect =
00072 TypeTraits<UInt32>::BitsSet;
00073
00074
00075
00076
00077 ChangeList *ThreadCommonBase::getChangeList(void)
00078 {
00079 return _pChangeList;
00080 }
00081
00082
00083
00084
00085 ThreadCommonBase::ThreadCommonBase(const Char8 *szName,
00086 UInt32 uiId) :
00087
00088 Inherited (szName,
00089 uiId ),
00090
00091 _uiAspectId (0 ),
00092 _pChangeList(NULL )
00093 {
00094 }
00095
00096
00097
00098
00099 ThreadCommonBase::~ThreadCommonBase(void)
00100 {
00101 subRefP(_pChangeList);
00102 }
00103
00104
00105
00106
00107 void ThreadCommonBase::setAspect(UInt32 uiAspectId)
00108 {
00109 _uiAspectId = uiAspectId;
00110 }
00111
00112 void ThreadCommonBase::setChangeList(ChangeList *pChangeList)
00113 {
00114 setRefP(_pChangeList, pChangeList);
00115 }
00116
00117
00118
00119
00120 #if defined (OSG_USE_PTHREADS)
00121
00122 #if defined(OSG_PTHREAD_ELF_TLS)
00123 __thread UInt32 PThreadBase::_uiTLSAspectId = 0;
00124 __thread ChangeList *PThreadBase::_pTLSChangeList = NULL;
00125 #else
00126 pthread_key_t PThreadBase::_aspectKey;
00127 pthread_key_t PThreadBase::_changeListKey;
00128 #endif
00129
00130
00131
00132
00133 UInt32 PThreadBase::getAspect(void)
00134 {
00135 #if defined(OSG_PTHREAD_ELF_TLS)
00136 return _uiTLSAspectId;
00137 #else
00138 UInt32 *pUint;
00139
00140 pUint = (UInt32 *) pthread_getspecific(_aspectKey);
00141
00142 return *pUint;
00143 #endif
00144
00145 }
00146
00147 ChangeList *PThreadBase::getCurrentChangeList(void)
00148 {
00149 #if defined(OSG_PTHREAD_ELF_TLS)
00150 return _pTLSChangeList;
00151 #else
00152 ChangeList **pCList;
00153
00154 pCList = (ChangeList **) pthread_getspecific(_changeListKey);
00155
00156 return *pCList;
00157 #endif
00158 }
00159
00160
00161
00162
00163
00164
00165 bool PThreadBase::runFunction(ThreadFuncF fThreadFunc,
00166 UInt32 uiAspectId,
00167 void *pThreadArg)
00168 {
00169 if(uiAspectId >= ThreadManager::getNumAspects())
00170 {
00171 SFATAL << "OSGPTB : invalid aspect id" << std::endl;
00172 return false;
00173 }
00174
00175 Inherited::setAspect(uiAspectId);
00176
00177 return Inherited::runFunction(fThreadFunc, pThreadArg);
00178 }
00179
00180
00181
00182
00183 #if !defined(OSG_PTHREAD_ELF_TLS)
00184 void PThreadBase::freeAspect(void *pAspect)
00185 {
00186 UInt32 *pUint = (UInt32 *) pAspect;
00187
00188 if(pUint != NULL)
00189 delete pUint;
00190 }
00191
00192 void PThreadBase::freeChangeList(void *pChangeList)
00193 {
00194 ChangeList **pCl = (ChangeList **) pChangeList;
00195
00196 if(pCl != NULL)
00197 delete pCl;
00198 }
00199 #endif
00200
00201
00202
00203
00204 PThreadBase::PThreadBase(const Char8 *szName,
00205 UInt32 uiId) :
00206 Inherited(szName, uiId)
00207 {
00208 }
00209
00210
00211
00212
00213 PThreadBase::~PThreadBase(void)
00214 {
00215 }
00216
00217
00218
00219
00220 void PThreadBase::init(void)
00221 {
00222 if(_bInitialized == true)
00223 return;
00224
00225 Inherited::init();
00226
00227 if(_bInitialized == true)
00228 {
00229 setupAspect ();
00230 setupChangeList();
00231 }
00232 }
00233
00234
00235 void PThreadBase::setupAspect(void)
00236 {
00237
00238 #if defined(OSG_PTHREAD_ELF_TLS)
00239 _uiTLSAspectId = Inherited::_uiAspectId;
00240 #else
00241 UInt32 *pUint = new UInt32;
00242
00243 *pUint = Inherited::_uiAspectId;
00244
00245 pthread_setspecific(_aspectKey, (void *) pUint);
00246 #endif
00247 }
00248
00249 void PThreadBase::setupChangeList(void)
00250 {
00251 #if defined(OSG_PTHREAD_ELF_TLS)
00252 if(Inherited::_pChangeList == NULL)
00253 {
00254 _pTLSChangeList = new ChangeList;
00255
00256 Inherited::setChangeList(_pTLSChangeList);
00257 }
00258 else
00259 {
00260 _pTLSChangeList = Inherited::_pChangeList;
00261
00262 _pTLSChangeList->clearAll();
00263 }
00264
00265 _pTLSChangeList->setAspect(Inherited::_uiAspectId);
00266 #else
00267 ChangeList **pChangeList = new ChangeList *;
00268
00269 if(Inherited::_pChangeList == NULL)
00270 {
00271 *pChangeList = new ChangeList;
00272
00273 Inherited::setChangeList(*pChangeList);
00274 }
00275 else
00276 {
00277 *pChangeList = Inherited::_pChangeList;
00278
00279 (*pChangeList)->clearAll();
00280 }
00281
00282 (*pChangeList)->setAspect(Inherited::_uiAspectId);
00283 pthread_setspecific(_changeListKey, (void *) pChangeList);
00284 #endif
00285 }
00286
00287 #endif
00288
00289
00290
00291
00292 #if defined (OSG_USE_SPROC)
00293
00294
00295
00296
00297 UInt32 SprocBase::getAspect(void)
00298 {
00299 return ((OSGProcessData *) PRDA->usr_prda.fill)->_uiAspectId;
00300 }
00301
00302 ChangeList *SprocBase::getCurrentChangeList(void)
00303 {
00304 return ((OSGProcessData *) PRDA->usr_prda.fill)->_pChangeList;
00305 }
00306
00307
00308
00309
00310
00311
00312 bool SprocBase::runFunction(ThreadFuncF fThreadFunc,
00313 UInt32 uiAspectId,
00314 void *pThreadArg)
00315 {
00316 if(uiAspectId >= ThreadManager::getNumAspects())
00317 {
00318 SFATAL << "OSGPTB : invalid aspect id" << std::endl;
00319 return false;
00320 }
00321
00322 Inherited::setAspect(uiAspectId);
00323
00324 return Inherited::runFunction(fThreadFunc, pThreadArg);
00325 }
00326
00327
00328
00329
00330 SprocBase::SprocBase(const Char8 *szName,
00331 UInt32 uiId) :
00332 Inherited(szName, uiId)
00333 {
00334 }
00335
00336
00337
00338
00339 SprocBase::~SprocBase(void)
00340 {
00341 }
00342
00343
00344
00345
00346 void SprocBase::setAspectInternal(UInt32 uiAspect)
00347 {
00348 ((OSGProcessData *) PRDA->usr_prda.fill)->_uiAspectId = uiAspect;
00349 }
00350
00351
00352
00353
00354 void SprocBase::init(void)
00355 {
00356 if(_bInitialized == true)
00357 return;
00358
00359 Inherited::init();
00360
00361 if(_bInitialized == true)
00362 {
00363 setAspectInternal (this->_uiAspectId);
00364 setupChangeListInternal();
00365 }
00366 }
00367
00368 void SprocBase::setupChangeListInternal(void)
00369 {
00370 if(Inherited::_pChangeList == NULL)
00371 {
00372 ((OSGProcessData *) PRDA->usr_prda.fill)->_pChangeList =
00373 new ChangeList();
00374
00375 Inherited::setChangeList(
00376 ((OSGProcessData *) PRDA->usr_prda.fill)->_pChangeList);
00377 }
00378 else
00379 {
00380 ((OSGProcessData *) PRDA->usr_prda.fill)->_pChangeList =
00381 Inherited::_pChangeList;
00382
00383 Inherited::_pChangeList->clearAll();
00384 }
00385
00386 Inherited::_pChangeList->setAspect(Inherited::_uiAspectId);
00387 }
00388
00389 #endif
00390
00391
00392
00393
00394 #if defined (OSG_USE_WINTHREADS)
00395
00396 #if defined(OSG_ASPECT_USE_LOCALSTORAGE)
00397 UInt32 WinThreadBase::_aspectKey = 0;
00398 UInt32 WinThreadBase::_changeListKey = 0;
00399 #endif
00400
00401 #if defined(OSG_ASPECT_USE_DECLSPEC)
00402 __declspec (thread) UInt32 WinThreadBase::_uiAspectLocal = 0;
00403 __declspec (thread) ChangeList *WinThreadBase::_pChangeListLocal = NULL;
00404 #endif
00405
00406
00407
00408
00409 UInt32 WinThreadBase::getAspect(void)
00410 {
00411 #ifdef OSG_ASPECT_USE_LOCALSTORAGE
00412 UInt32 *pUint;
00413
00414 pUint = (UInt32 *) TlsGetValue(_aspectKey);
00415
00416 return *pUint;
00417 #endif
00418 #ifdef OSG_ASPECT_USE_DECLSPEC
00419 return _uiAspectLocal;
00420 #endif
00421 }
00422
00423 ChangeList *WinThreadBase::getCurrentChangeList(void)
00424 {
00425 #ifdef OSG_ASPECT_USE_LOCALSTORAGE
00426 ChangeList **pCList;
00427
00428 pCList = (ChangeList **) TlsGetValue(_changeListKey);
00429
00430 return *pCList;
00431 #endif
00432 #ifdef OSG_ASPECT_USE_DECLSPEC
00433 return _pChangeListLocal;
00434 #endif
00435 }
00436
00437
00438
00439
00440
00441
00442 bool WinThreadBase::runFunction(ThreadFuncF fThreadFunc,
00443 UInt32 uiAspectId,
00444 void *pThreadArg)
00445 {
00446 if(uiAspectId >= ThreadManager::getNumAspects())
00447 {
00448 SFATAL << "OSGPTB : invalid aspect id" << std::endl;
00449 return false;
00450 }
00451
00452 Inherited::setAspect(uiAspectId);
00453
00454 return Inherited::runFunction(fThreadFunc, pThreadArg);
00455 }
00456
00457
00458
00459
00460 #if defined (OSG_ASPECT_USE_LOCALSTORAGE)
00461 void WinThreadBase::freeAspect(void)
00462 {
00463 UInt32 *pUint;
00464
00465 pUint = (UInt32 *) TlsGetValue(_aspectKey);
00466
00467 delete pUint;
00468 }
00469
00470 void WinThreadBase::freeChangeList(void)
00471 {
00472 ChangeList **pCList;
00473
00474 pCList = (ChangeList **) TlsGetValue(_changeListKey);
00475
00476 delete pCList;
00477 }
00478 #endif
00479
00480
00481
00482
00483 WinThreadBase::WinThreadBase(const Char8 *szName,
00484 UInt32 uiId) :
00485 Inherited(szName, uiId)
00486 {
00487 }
00488
00489
00490
00491
00492 WinThreadBase::~WinThreadBase(void)
00493 {
00494 }
00495
00496
00497
00498
00499 void WinThreadBase::init(void)
00500 {
00501 if(_bInitialized == true)
00502 return;
00503
00504 Inherited::init();
00505
00506 if(_bInitialized == true)
00507 {
00508 setupAspect ();
00509 setupChangeList();
00510 }
00511 }
00512
00513 void WinThreadBase::setupAspect(void)
00514 {
00515 #ifdef OSG_ASPECT_USE_LOCALSTORAGE
00516 UInt32 *pUint = new UInt32;
00517
00518 *pUint = Inherited::_uiAspectId;
00519
00520 TlsSetValue(_aspectKey, pUint);
00521 #endif
00522
00523 #ifdef OSG_ASPECT_USE_DECLSPEC
00524 _uiAspectLocal = Inherited::_uiAspectId;
00525 #endif
00526 }
00527
00528 void WinThreadBase::setupChangeList(void)
00529 {
00530 #if defined (OSG_ASPECT_USE_LOCALSTORAGE)
00531 ChangeList **pChangeList = new ChangeList *;
00532
00533 if(Inherited::_pChangeList == NULL)
00534 {
00535 *pChangeList = new ChangeList;
00536
00537 Inherited::setChangeList(*pChangeList);
00538 }
00539 else
00540 {
00541 *pChangeList = Inherited::_pChangeList;
00542
00543 (*pChangeList)->clearAll();
00544 }
00545
00546 (*pChangeList)->setAspect(Inherited::_uiAspectId);
00547 TlsSetValue(_changeListKey, pChangeList);
00548 #endif
00549
00550 #if defined (OSG_ASPECT_USE_DECLSPEC)
00551 if(Inherited::_pChangeList == NULL)
00552 {
00553 _pChangeListLocal = new ChangeList;
00554 Inherited::setChangeList(_pChangeListLocal);
00555 }
00556 else
00557 {
00558 _pChangeListLocal = Inherited::_pChangeList;
00559
00560 _pChangeListLocal->clearAll();
00561 }
00562
00563 _pChangeListLocal->setAspect(Inherited::_uiAspectId);
00564 #endif
00565 }
00566
00567 #endif
00568
00569
00570
00571
00572 MPThreadType Thread::_type("OSGThread",
00573 "OSGBaseThread",
00574 (CreateThreadF) Thread::create,
00575 (InitThreadingF) Thread::initThreading);
00576
00577
00578
00579
00580 ThreadBase *Thread::getCurrent(void)
00581 {
00582 return static_cast<ThreadBase *>(Inherited::getCurrent());
00583 }
00584
00585 Thread *Thread::get(const Char8 *szName)
00586 {
00587 BaseThread *pThread = ThreadManager::the()->getThread(szName, "OSGThread");
00588
00589 return dynamic_cast<Thread *>(pThread);
00590 }
00591
00592 Thread *Thread::find(const Char8 *szName)
00593 {
00594 BaseThread *pThread = ThreadManager::the()->findThread(szName);
00595
00596 return dynamic_cast<Thread *>(pThread);
00597 }
00598
00599 void Thread::run(UInt32 uiAspectId)
00600 {
00601 Inherited::runFunction(runWorkProc, uiAspectId, this);
00602 }
00603
00604
00605
00606
00607 Thread *Thread::create(const Char8 *szName, UInt32 uiId)
00608 {
00609 return new Thread(szName, uiId);
00610 }
00611
00612 void Thread::initThreading(void)
00613 {
00614 FINFO(("Thread::initThreading\n"))
00615
00616 #if defined(OSG_USE_PTHREADS) && !defined(OSG_PTHREAD_ELF_TLS)
00617 int rc;
00618
00619 rc = pthread_key_create(&(Thread::_aspectKey),
00620 Thread::freeAspect);
00621
00622 FFASSERT((rc == 0), 1, ("Failed to create pthread aspect key\n");)
00623
00624 rc = pthread_key_create(&(Thread::_changeListKey),
00625 Thread::freeChangeList);
00626
00627 FFASSERT((rc == 0), 1, ("Failed to create pthread changelist key\n");)
00628 #endif
00629
00630 #if defined(OSG_USE_WINTHREADS) && defined(OSG_ASPECT_USE_LOCALSTORAGE)
00631 Thread::_aspectKey = TlsAlloc();
00632
00633 FFASSERT((Thread::_aspectKey != 0xFFFFFFFF), 1,
00634 ("Failed to alloc aspect key local storage\n");)
00635
00636 Thread::_changeListKey = TlsAlloc();
00637
00638 FFASSERT((Thread::_changeListKey != 0xFFFFFFFF), 1,
00639 ("Failed to alloc changelist key local storage\n");)
00640 #endif
00641
00642 ThreadManager::setAppThreadType("OSGThread");
00643 }
00644
00645
00646
00647
00648 Thread::Thread(const Char8 *szName, UInt32 uiId) :
00649 Inherited(szName, uiId)
00650 {
00651 }
00652
00653
00654
00655
00656 Thread::~Thread(void)
00657 {
00658 }
00659
00660
00661
00662
00663 MPThreadType ExternalThread::_type("OSGExternalThread",
00664 "OSGMPBase",
00665 (CreateThreadF) ExternalThread::create,
00666 NULL);
00667
00668
00669
00670
00671 ThreadBase *ExternalThread::getCurrent(void)
00672 {
00673 return static_cast<ThreadBase *>(Inherited::getCurrent());
00674 }
00675
00676 ExternalThread *ExternalThread::get(const Char8 *szName)
00677 {
00678 BaseThread *pThread = ThreadManager::the()->getThread(szName,
00679 "OSGExternalThread");
00680
00681 return dynamic_cast<ExternalThread *>(pThread);
00682 }
00683
00684 ExternalThread *ExternalThread::find(const Char8 *szName)
00685 {
00686 BaseThread *pThread = ThreadManager::the()->findThread(szName);
00687
00688 return dynamic_cast<ExternalThread *>(pThread);
00689 }
00690
00691 void ExternalThread::initialize(UInt32 uiAspectId)
00692 {
00693 if(_bInitialized == true)
00694 return;
00695
00696 Inherited::setAspect(uiAspectId);
00697
00698 this->init();
00699 }
00700
00701
00702
00703
00704 ExternalThread *ExternalThread::create(const Char8 *szName,
00705 UInt32 uiId)
00706 {
00707 return new ExternalThread(szName, uiId);
00708 }
00709
00710 #if 0
00711 void ExternalThread::initThreading(void)
00712 {
00713 FINFO(("Thread::initThreading\n"))
00714
00715 #ifdef OSG_ASPECT_USE_PTHREADKEY
00716 int rc;
00717
00718 rc = pthread_key_create(&(Thread::_aspectKey),
00719 Thread::freeAspect);
00720
00721 FFASSERT((rc == 0), 1, ("Failed to create pthread aspect key\n");)
00722
00723 rc = pthread_key_create(&(Thread::_changeListKey),
00724 Thread::freeChangeList);
00725
00726 FFASSERT((rc == 0), 1, ("Failed to create pthread changelist key\n");)
00727 #endif
00728
00729 #ifdef OSG_ASPECT_USE_PTHREADSELF
00730
00731 Thread::_vAspects .resize(16);
00732 Thread::_vChangelists.resize(16);
00733
00734 for(UInt32 i = 0; i < 16; i++)
00735 {
00736 Thread::_vAspects[i] = 0;
00737 Thread::_vChangelists[i] = NULL;
00738 }
00739 #endif
00740
00741 #if defined (OSG_ASPECT_USE_LOCALSTORAGE)
00742 Thread::_aspectKey = TlsAlloc();
00743
00744 FFASSERT((Thread::_aspectKey != 0xFFFFFFFF), 1,
00745 ("Failed to alloc aspect key local storage\n");)
00746
00747 Thread::_changeListKey = TlsAlloc();
00748
00749 FFASSERT((Thread::_changeListKey != 0xFFFFFFFF), 1,
00750 ("Failed to alloc changelist key local storage\n");)
00751 #endif
00752
00753 ThreadManager::setAppThreadType("OSGThread");
00754 }
00755 #endif
00756
00757
00758
00759
00760 ExternalThread::ExternalThread(const Char8 *szName, UInt32 uiId) :
00761 Inherited(szName, uiId)
00762 {
00763 }
00764
00765
00766
00767
00768 ExternalThread::~ExternalThread(void)
00769 {
00770 }
00771
00772
00773
00774
00775
00776 #ifdef __sgi
00777 #pragma set woff 1174
00778 #endif
00779
00780 #ifdef OSG_LINUX_ICC
00781 #pragma warning( disable : 177 )
00782 #endif
00783
00784 namespace
00785 {
00786 static Char8 cvsid_cpp[] = "@(#)$Id: $";
00787 static Char8 cvsid_hpp[] = OSGTHREAD_HEADER_CVSID;
00788 }