CrystalSpace

Public API Reference

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.0 by doxygen 1.7.6.1