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 #ifndef _SB_THREAD_LOCAL_STORAGE_H_
00026 #define _SB_THREAD_LOCAL_STORAGE_H_
00027
00028 #include <Inventor/SbBase.h>
00029 #include <Inventor/STL/vector>
00030 #include <Inventor/threads/SbThreadSpinlock.h>
00031 #include <Inventor/errors/SoDebugError.h>
00032
00033 #if defined(_WIN32)
00034 #pragma warning( push )
00035 #pragma warning(disable:4251)
00036 #endif //_WIN32
00037
00038 typedef void SoInitTLSClassCB();
00039 typedef void SoExitTLSClassCB();
00040
00047 #define SB_THREAD_INIT_CLASS(_className_,_structName_) \
00048 if ( _className_::MT_Id == -1 ) \
00049 _className_::MT_Id = SbThreadLocalStorage::createStorage(sizeof(struct _className_::_structName_), _className_::initTLSClass, _className_::exitTLSClass, __FUNCTION__ ); \
00050 else \
00051 SoDebugError::post(__FUNCTION__,"SB_THREAD_INIT_CLASS called multiple time for class " SO__QUOTE(_className_));
00052
00059 #define SB_THREAD_EXIT_CLASS(_className_) \
00060 SbThreadLocalStorage::deleteStorage( _className_::MT_Id ); \
00061 _className_::MT_Id = -1;
00062
00066 #define GET_THREAD_LOCAL_VAR(_className_, _structName_, _varName_) \
00067 \
00068 ((static_cast<struct _className_::_structName_ *> (SbThreadLocalStorage::getStorage(_className_::MT_Id)))->_varName_)
00069
00073 #define GET_THREAD_LOCAL_STORAGE(_className_) \
00074 \
00075 (static_cast<void *> (SbThreadLocalStorage::getStorage(_className_::MT_Id)))
00076
00080 #define SB_THREAD_TLS_HEADER() \
00081 private: \
00082 \
00083 static size_t MT_Id; \
00084 \
00085 static void initTLSClass(); \
00086 \
00087 static void exitTLSClass()
00088
00089
00093 #define SB_THREAD_TLS_SOURCE( _className_ ) \
00094 \
00095 \
00096 size_t _className_::MT_Id = -1
00097
00099 #ifndef SoNodeTLS
00100 #define SoNodeTLS SbThreadLocalStorage
00101 #endif
00102
00215 class SbThreadLocalStorage
00216 {
00217 public:
00225 static size_t createStorage(const size_t byteSize, SoInitTLSClassCB* initFunc=NULL, SoExitTLSClassCB* exitFunc=NULL, const char* funcName=NULL);
00226
00230 static void deleteStorage( size_t id );
00231
00238 static void *getStorage(const size_t classThreadId);
00239
00240 private:
00253 static void initThreadLocalStorage();
00254
00260 static void closeThreadLocalStorage();
00261
00267 static void exitThreadLocalStorage();
00268
00269 private:
00275 static void initClass();
00276
00281 static void exitClass();
00282
00287 template<typename StructName, typename ClassName>
00288 static StructName*
00289 getStruct()
00290 {
00291 return static_cast<StructName*>(SbThreadLocalStorage::getStorage(ClassName::MT_Id));
00292 }
00293
00298 template<typename StructName, typename ClassName>
00299 static StructName*
00300 getStruct(const ClassName*)
00301 {
00302 return getStruct<StructName, ClassName>();
00303 }
00304
00308 static bool isInitialized()
00309 { return (getThreadStorage()!=NULL); }
00310
00311 private:
00313 static void checkInitTLS();
00314
00315
00316 class StorageInfo
00317 {
00318 public:
00319
00320 size_t size;
00321
00322
00323 SoInitTLSClassCB* initFunc;
00324
00325
00326 SoExitTLSClassCB* exitFunc;
00327
00328
00329 StorageInfo() : size(0),initFunc(NULL),exitFunc(NULL) {}
00330 };
00331
00332
00333 static SbThreadSpinlock s_storageInfoListLock;
00334
00335
00336 typedef std::vector<StorageInfo*> SoStorageInfoList;
00337 static SoStorageInfoList s_storageInfoList;
00338
00339
00340 typedef std::vector<void*> SoStorageList;
00341
00342 static SoStorageList* s_threadStorageList;
00343
00344 static SoStorageList* getThreadStorage();
00345 };
00346
00347
00348 #if defined(_WIN32)
00349 #pragma warning(pop)
00350 #endif //_WIN32
00351
00352
00353 #endif //_SB_THREAD_LOCAL_STORAGE_H_
00354
00355
00356
00357
00358