Gray C++ Libraries  0.0.2
A set of C++ libraries for MSVC, GNU on Windows, WinCE, Linux
cThreadLocalSys.h
Go to the documentation of this file.
1 //
4 //
5 
6 #ifndef _INC_cThreadLocalSys_H
7 #define _INC_cThreadLocalSys_H
8 #ifndef NO_PRAGMA_ONCE
9 #pragma once
10 #endif
11 
12 #include "GrayCore.h"
13 #include "cDebugAssert.h"
14 
15 #ifdef __linux__
16 #include <pthread.h> // pthread_key_t
17 #endif
18 
19 #if defined(_WIN32) && defined(__GNUC__)
20 typedef VOID (NTAPI *PFLS_CALLBACK_FUNCTION) ( PVOID lpFlsData );
21 WINBASEAPI DWORD WINAPI FlsAlloc( PFLS_CALLBACK_FUNCTION lpCallback ); // replace TlsAlloc()
22 WINBASEAPI BOOL WINAPI FlsFree( DWORD dwFlsIndex );
23 WINBASEAPI PVOID WINAPI FlsGetValue( DWORD dwFlsIndex );
24 WINBASEAPI BOOL WINAPI FlsSetValue( DWORD dwFlsIndex, PVOID lpFlsData );
25 #endif
26 
27 namespace Gray
28 {
30  {
36  virtual void* GetDataNewV() = 0;
38  };
39 
41  {
47 
48  public:
49 #ifdef _WIN32
50 #ifndef TLS_OUT_OF_INDEXES
51 #define TLS_OUT_OF_INDEXES 0xffffffff // TLS_OUT_OF_INDEXES not defined on UNDER_CE
52 #endif
53  typedef DWORD TYPESLOT_t;
54 #elif defined(__linux__)
55 #define TLS_OUT_OF_INDEXES ((pthread_key_t)-1)
56 #define NTAPI
57  typedef pthread_key_t TYPESLOT_t;
58  typedef void (NTAPI *PFLS_CALLBACK_FUNCTION)(IN void *p); // like FARPROC
59 #else
60 #error NOOS
61 #endif
62 
63  private:
64  TYPESLOT_t m_nTypeSlot;
65 
66  public:
67  cThreadLocalSys(PFLS_CALLBACK_FUNCTION pDestruct = nullptr) noexcept
68  {
71 #ifdef _WIN32
72  // Use newer FlsAlloc (has destructor) over old XP specific TlsAlloc. limited to 128 uses.
73 #if (_WIN32_WINNT >= 0x0600)
74  m_nTypeSlot = ::FlsAlloc(pDestruct);
75 #else
76  m_nTypeSlot = ::TlsAlloc();
77 #endif
78 #else // __linux__
79  int iRet = ::pthread_key_create( &m_nTypeSlot, pDestruct);
80  if (iRet!=0)
81  {
82  m_nTypeSlot = TLS_OUT_OF_INDEXES; // failed for some reason.
83  }
84 #endif
86  }
88  {
90 #ifdef _WIN32
91 #if (_WIN32_WINNT >= 0x0600)
92  ::FlsFree(m_nTypeSlot);
93 #else
94  ::TlsFree(m_nTypeSlot);
95 #endif
96 #else // __linux__
97  int iRet = ::pthread_key_delete(m_nTypeSlot);
98  ASSERT(iRet==0);
100 #endif
101  }
102  bool isInit() const noexcept
103  {
105 #ifdef _WIN32
106  if (m_nTypeSlot == 0)
107  return false;
108 #endif
109  if (m_nTypeSlot == TLS_OUT_OF_INDEXES)
110  return false;
111  return true;
112  }
113 
114  void* GetData() const noexcept
115  {
118  if (!isInit())
119  {
120  // DEBUG_CHECK(0);
121  return nullptr; // Before static init!
122  }
123 #ifdef _WIN32
124 #if (_WIN32_WINNT >= 0x0600)
125  return ::FlsGetValue(m_nTypeSlot);
126 #else
127  return ::TlsGetValue(m_nTypeSlot);
128 #endif
129 #else // __linux__
130  return ::pthread_getspecific(m_nTypeSlot);
131 #endif
132  }
133 
134  bool PutData(void* pData) noexcept
135  {
137  DEBUG_CHECK(isInit()); // Before static init!
138 #ifdef _WIN32
139 #if (_WIN32_WINNT >= 0x0600)
140  return ::FlsSetValue(m_nTypeSlot, pData) ? true : false;
141 #else
142  return ::TlsSetValue(m_nTypeSlot, pData) ? true : false;
143 #endif
144 #else // __linux__
145  int iRet = ::pthread_setspecific(m_nTypeSlot, pData );
146  return iRet == 0 ;
147 #endif
148  }
149  };
150 
151  template <class TYPE>
153  {
158 
159  typedef cThreadLocalSys SUPER_t;
160 
161  public:
162  cThreadLocalSysT(PFLS_CALLBACK_FUNCTION pDestruct = nullptr) noexcept
163  : cThreadLocalSys(pDestruct)
164  {
165  STATIC_ASSERT(sizeof(TYPE) <= sizeof(void*), cThreadLocalSysT); // ?
166  }
167  TYPE GetData() const noexcept
168  {
169  return (TYPE)SUPER_t::GetData();
170  }
171  bool PutData(TYPE nData) noexcept
172  {
173  return SUPER_t::PutData((void*)nData);
174  }
175  };
176 
177  template <class TYPE>
178  class cThreadLocalSysNew : public cThreadLocalSysT<TYPE*>, public IThreadLocal
179  {
184 
185  protected:
186  static void NTAPI OnThreadClose(IN void* pData)
187  {
189  ASSERT(pData != nullptr);
190  TYPE* pData2 = (TYPE*)pData;
191  delete pData2;
192  }
193 
194  public:
197  {
198  }
199 
200  TYPE* GetDataNew() // GetData
201  {
203  TYPE* pData = SUPER_t::GetData();
204  if (pData == nullptr)
205  {
206  pData = new TYPE;
207  SUPER_t::PutData(pData);
208  }
209  return pData;
210  }
211  virtual void* GetDataNewV()
212  {
215  return GetDataNew();
216  }
218  {
220  TYPE* pData = SUPER_t::GetData();
221  if (pData != nullptr)
222  {
223  SUPER_t::PutData(nullptr);
224  delete pData;
225  }
226  }
227  };
228 }
229 #endif
#define IGNORE_WARN_INTERFACE(c)
Definition: GrayCore.h:79
#define TYPE
Definition: StrT.cpp:38
#define UNREFERENCED_PARAMETER(P)
< _WIN32 type thing. get rid of stupid warning.
Definition: SysTypes.h:299
#define ASSERT(exp)
Definition: cDebugAssert.h:87
#define STATIC_ASSERT(exp, name)
Definition: cDebugAssert.h:24
#define DEBUG_CHECK(exp)
Definition: cDebugAssert.h:90
Definition: cThreadLocalSys.h:179
static void NTAPI OnThreadClose(IN void *pData)
Definition: cThreadLocalSys.h:186
virtual void * GetDataNewV()
Definition: cThreadLocalSys.h:211
void FreeDataManually()
Definition: cThreadLocalSys.h:217
cThreadLocalSysNew() noexcept
Definition: cThreadLocalSys.h:195
TYPE * GetDataNew()
Definition: cThreadLocalSys.h:200
Definition: cThreadLocalSys.h:153
TYPE GetData() const noexcept
Definition: cThreadLocalSys.h:167
bool PutData(TYPE nData) noexcept
Definition: cThreadLocalSys.h:171
cThreadLocalSysT(PFLS_CALLBACK_FUNCTION pDestruct=nullptr) noexcept
Definition: cThreadLocalSys.h:162
Definition: cThreadLocalSys.h:41
~cThreadLocalSys()
Definition: cThreadLocalSys.h:87
cThreadLocalSys(PFLS_CALLBACK_FUNCTION pDestruct=nullptr) noexcept
Definition: cThreadLocalSys.h:67
void * GetData() const noexcept
Definition: cThreadLocalSys.h:114
bool isInit() const noexcept
Definition: cThreadLocalSys.h:102
bool PutData(void *pData) noexcept
Definition: cThreadLocalSys.h:134
< The main namespace for all Core functions.
Definition: GrayCore.cpp:14
DECLARE_INTERFACE(IRandomNoise)
Definition: cThreadLocalSys.h:30
virtual void * GetDataNewV()=0