csutil/threading/tls.h
Go to the documentation of this file.00001 /* 00002 Copyright (C) 2008 by Michael Gist 00003 00004 This library is free software; you can redistribute it and/or 00005 modify it under the terms of the GNU Lesser General Public 00006 License as published by the Free Software Foundation; either 00007 version 2 of the License, or (at your option) any later version. 00008 00009 This library is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 Library General Public License for more details. 00013 00014 You should have received a copy of the GNU Library General Public 00015 License along with this library; if not, write to the Free 00016 Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 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 // Destructor function does _not_ kick in when deleting the TLS slot! 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 } // Threading 00155 } // CS 00156 00157 #endif // __CS_CSUTIL_THREADING_TLS_H__
Generated for Crystal Space 2.1 by doxygen 1.6.1
