00001
00002 #ifndef CG_TLS_HPP
00003 #define CG_TLS_HPP
00004
00005 #if defined(_MSC_VER) // Visual C++ version
00006
00007 namespace cg
00008 {
00010
00013 template<typename T, typename Tag=T>
00014 class tls
00015 {
00016 static T & value()
00017 {
00018 static __declspec(thread) T value;
00019 return value;
00020 }
00021
00022 public:
00023 static T get() { return value(); }
00024 static void set(T t) { value() = t; }
00025 };
00026 }
00027
00028 #else
00029
00030 #include <pthread.h>
00031
00032 namespace cg
00033 {
00035 class tls_key : cg::not_copyable, cg::not_assignable
00036 {
00037 pthread_key_t m_key;
00038 public:
00039 tls_key()
00040 {
00041 if( pthread_key_create(&m_key, 0) )
00042 throw std::runtime_error("Error creating key");
00043 }
00044
00045 ~tls_key()
00046 {
00047 pthread_key_delete(m_key);
00048 }
00049
00050 pthread_key_t get() const
00051 {
00052 return m_key;
00053 }
00054 };
00055
00056
00057 template<typename T, typename Tag=T>
00058 class tls;
00059
00061 template<typename T, typename Tag>
00062 class tls<T*, Tag>
00063 {
00064 static pthread_key_t my_key()
00065 {
00066 static tls_key k;
00067 return k.get();
00068 }
00069
00070 public:
00071 static T* get()
00072 {
00073 return static_cast<T*>(pthread_getspecific( my_key() ));
00074 }
00075
00076 static void set(T* v)
00077 {
00078 pthread_setspecific( my_key(), static_cast<void*>(v) );
00079 }
00080 };
00081 }
00082
00083 #endif
00084
00085 #endif