Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00022 #ifndef __CS_CSUTIL_THREADING_TLS_H__
00023 #define __CS_CSUTIL_THREADING_TLS_H__
00024
00025 #include "../noncopyable.h"
00026
00027 #if defined(CS_PLATFORM_WIN32)
00028 # include "csutil/threading/win32_tls.h"
00029 #elif defined(CS_PLATFORM_UNIX) || \
00030 defined(CS_PLATFORM_MACOSX)
00031 # include "csutil/threading/pthread_tls.h"
00032 #else
00033 #ifndef DOXYGEN_RUN
00034 #error "No TLS implementation for your platform"
00035 #endif
00036 #endif
00037
00038 namespace CS
00039 {
00040 namespace Threading
00041 {
00042 using namespace Implementation;
00043
00044 #ifdef DOXYGEN_RUN
00045
00058 class ThreadLocalBase
00059 {
00060 public:
00062 typedef void (* DestructorFn)(void*);
00063
00065 ThreadLocalBase (DestructorFn dtor = 0);
00067 ~ThreadLocalBase();
00069 void SetValue (void* data) const;
00071 void* GetValue () const;
00072 };
00073 #endif
00074
00085 template<typename T>
00086 class ThreadLocal : protected ThreadLocalBase,
00087 public CS::NonCopyable
00088 {
00089 static void Destructor (void* p)
00090 {
00091 delete reinterpret_cast<T*> (p);
00092 }
00093
00095 T& GetObject() const
00096 {
00097 T* p = reinterpret_cast<T*> (ThreadLocalBase::GetValue ());
00098 if (p == 0)
00099 {
00100 p = new T;
00101 ThreadLocalBase::SetValue (p);
00102 }
00103 return *p;
00104 }
00105 public:
00106 ThreadLocal() : ThreadLocalBase (Destructor)
00107 {
00108 }
00109 ~ThreadLocal()
00110 {
00111
00112 T* p = reinterpret_cast<T*> (ThreadLocalBase::GetValue ());
00113 delete p;
00114 }
00115
00117 bool HasValue() const
00118 {
00119 return ThreadLocalBase::GetValue () != 0;
00120 }
00121
00123 operator T& () const
00124 {
00125 return GetObject();
00126 }
00127
00129 T* operator->() const
00130 {
00131 return &(GetObject());
00132 }
00133
00135 T& operator *() const
00136 {
00137 return GetObject();
00138 }
00139
00141 ThreadLocal& operator = (const T& other)
00142 {
00143 T* p = reinterpret_cast<T*> (ThreadLocalBase::GetValue ());
00144 if (p == 0)
00145 {
00146 p = new T (other);
00147 ThreadLocalBase::SetValue (p);
00148 }
00149 else
00150 *p = other;
00151 return *this;
00152 }
00153 };
00154 }
00155 }
00156
00157 #endif // __CS_CSUTIL_THREADING_TLS_H__