csutil/threading/tls.h Source File (Crystal Space 2.0 Public API Reference)

| ## Public API Reference

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

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__