Gray C++ Libraries  0.0.2
A set of C++ libraries for MSVC, GNU on Windows, WinCE, Linux
cThreadLocal.h
Go to the documentation of this file.
1 //
6 
7 #ifndef _INC_cThreadLocal_H
8 #define _INC_cThreadLocal_H
9 #ifndef NO_PRAGMA_ONCE
10 #pragma once
11 #endif
12 
13 #include "cThreadMgr.h"
21 
22 namespace GrayLib
23 {
24  UNITTEST2_PREDEF(cThreadLocal);
25 
26  template <class TYPE, class TYPE_ARG>
28  {
33 
35 
36  private:
37  // Sorted / searched by this param
38  THREADID_t m_nThreadId;
39  TYPE m_Data;
40 
41  public:
42  cThreadLocalInst() noexcept
43  : m_nThreadId(cThreadId::k_NULL)
44  {
45  // used just for arrays.
46  }
47  cThreadLocalInst(THREADID_t nThreadID) noexcept
48  : m_nThreadId(nThreadID)
49  {
50  DEBUG_CHECK(nThreadID != cThreadId::k_NULL);
51  }
53  {
54  }
55  THREADID_t get_HashCode() const noexcept
56  {
57  return m_nThreadId;
58  }
59  TYPE_ARG get_Data() const noexcept
60  {
61  return m_Data;
62  }
63  void put_Data(TYPE_ARG rData)
64  {
65  // NOTE: Always use this to prevent problems with M$ constructors from calling destructor in imbalanced way.
66  m_Data = rData;
67  }
68 
69  UNITTEST2_PREDEF(cThreadLocal );
70  };
71 
72  template <class TYPE_INST, class TYPE_ARG>
74  : public IThreadCloseHandler
75  , public IThreadLocal // must implement this.
76  {
80 
81  public:
83  protected:
84  cArraySortStructHash< TYPE_INST, THREADID_t > m_a; // Track an instance of TYPE_INST for each active thread.
85 
86  private:
87  TYPE_ARG GetDataForX(THREADID_t nThreadID) const
88  {
90  ITERATE_t i = m_a.FindIForKey(nThreadID);
91  if (i < 0)
92  return nullptr; // always a pointer!
93  return m_a.GetAt(i).get_Data();
94  }
95 
96  public:
98  {
100  cThreadMgr::I().Register(this);
101  }
103  {
105  {
106  cThreadMgr::I().UnRegister(this);
107  }
108  }
109  TYPE_ARG GetDataForThreadId(THREADID_t nThreadID) const
110  {
112  cThreadGuardFast threadguard(m_Lock); // thread sync critical section.
113  return GetDataForX(nThreadID);
114  }
115  TYPE_ARG GetData() const
116  {
118  cThreadGuardFast threadguard(m_Lock); // thread sync critical section.
119  THREADID_t nThreadID = m_Lock.get_ThreadLockOwner();
120  ASSERT(nThreadID == cThreadId::GetCurrentId());
121  return GetDataForX(nThreadID);
122  }
123  bool PutData(TYPE_ARG Data)
124  {
126  cThreadGuardFast threadguard(m_Lock); // thread sync critical section.
127  THREADID_t nThreadID = m_Lock.get_ThreadLockOwner();
128  ASSERT(nThreadID == cThreadId::GetCurrentId());
129  ITERATE_t i = m_a.FindIForKey(nThreadID);
130  if (i < 0)
131  {
132  i = m_a.Add(TYPE_INST(nThreadID));
133  }
134  // NOTE: Always use this to prevent problems with M$ constructors from calling destructor in imbalanced way.
135  m_a.ElementAt(i).put_Data(Data);
136  return(i >= 0);
137  }
138 
139  virtual void OnThreadClose(THREADID_t nThreadID)
140  {
143  cThreadGuardFast threadguard(m_Lock); // thread sync critical section.
144  m_a.RemoveKey(nThreadID); // destruct type if needed.
145  }
146 
147  // For debug purposes.
148 
149  void RemoveAll()
150  {
152  cThreadGuardFast threadguard(m_Lock); // thread sync critical section.
153  m_a.RemoveAll();
154  }
156  {
157  return m_a.GetSize();
158  }
159  bool IsEmpty() const
160  {
161  cThreadGuardFast threadguard(m_Lock); // thread sync critical section.
162  return m_a.IsEmpty();
163  }
164  };
165 
166  template <class TYPE>
167  class cThreadLocalTypeNew : public cThreadLocalType< cThreadLocalInst< cNewPtr2<TYPE>, TYPE*>, TYPE* >
168  {
171 
172  public:
175 
176  TYPE* GetDataNew() // GetData
177  {
179  TYPE* pData = SUPER_t::GetData();
180  if (pData == nullptr)
181  {
182  pData = new TYPE;
183  SUPER_t::PutData(pData);
184  }
185  return pData;
186  }
187  virtual void* GetDataNewV()
188  {
190  return GetDataNew();
191  }
192  };
193 
194  template <class TYPE>
195  class cThreadLocalTypeSmart : public cThreadLocalType< cThreadLocalInst< cRefPtr<TYPE>, TYPE*>, TYPE* >
196  {
199  public:
202 
203  TYPE* GetDataNew() // GetData
204  {
206  TYPE* pData = SUPER_t::GetData();
207  if (pData == nullptr)
208  {
209  pData = new TYPE;
210  SUPER_t::PutData(pData);
211  }
212  return pData;
213  }
214  virtual void* GetDataNewV()
215  {
217  return GetDataNew();
218  }
219  };
220 };
221 
222 #endif // _INC_cThreadLocal_H
#define TYPE
Definition: StrT.cpp:38
#define ASSERT(exp)
Definition: cDebugAssert.h:87
#define DEBUG_CHECK(exp)
Definition: cDebugAssert.h:90
Definition: cThreadLocal.h:28
TYPE_ARG get_Data() const noexcept
Definition: cThreadLocal.h:59
THREADID_t get_HashCode() const noexcept
Definition: cThreadLocal.h:55
void put_Data(TYPE_ARG rData)
Definition: cThreadLocal.h:63
cThreadLocalInst() noexcept
Definition: cThreadLocal.h:42
~cThreadLocalInst()
Definition: cThreadLocal.h:52
cThreadLocalInst(THREADID_t nThreadID) noexcept
Definition: cThreadLocal.h:47
UNITTEST2_PREDEF(cThreadLocal)
Definition: cThreadLocal.h:168
virtual void * GetDataNewV()
Definition: cThreadLocal.h:187
cThreadLocalType< TYPE_INST, TYPE * > SUPER_t
Definition: cThreadLocal.h:174
cThreadLocalInst< cNewPtr2< TYPE >, TYPE * > TYPE_INST
Definition: cThreadLocal.h:173
TYPE * GetDataNew()
Definition: cThreadLocal.h:176
Definition: cThreadLocal.h:196
virtual void * GetDataNewV()
Definition: cThreadLocal.h:214
cThreadLocalType< TYPE_INST, TYPE * > SUPER_t
Definition: cThreadLocal.h:201
cThreadLocalInst< cRefPtr< TYPE >, TYPE * > TYPE_INST
Definition: cThreadLocal.h:200
TYPE * GetDataNew()
Definition: cThreadLocal.h:203
Definition: cThreadLocal.h:76
cThreadLockFast m_Lock
Definition: cThreadLocal.h:82
ITERATE_t GetSize() const
Definition: cThreadLocal.h:155
TYPE_ARG GetData() const
Definition: cThreadLocal.h:115
bool PutData(TYPE_ARG Data)
Definition: cThreadLocal.h:123
void RemoveAll()
Definition: cThreadLocal.h:149
virtual void OnThreadClose(THREADID_t nThreadID)
Definition: cThreadLocal.h:139
bool IsEmpty() const
Definition: cThreadLocal.h:159
cThreadLocalType()
Definition: cThreadLocal.h:97
virtual ~cThreadLocalType()
Definition: cThreadLocal.h:102
TYPE_ARG GetDataForThreadId(THREADID_t nThreadID) const
Definition: cThreadLocal.h:109
cArraySortStructHash< TYPE_INST, THREADID_t > m_a
Definition: cThreadLocal.h:84
void RemoveAll()
Clean up.
Definition: cArray.h:230
bool IsEmpty() const noexcept
Definition: cArray.h:145
const TYPE & GetAt(ITERATE_t nIndex) const
Definition: cArray.h:162
TYPE & ElementAt(ITERATE_t nIndex)
Definition: cArray.h:167
ITERATE_t GetSize() const noexcept
Definition: cArray.h:137
ITERATE_t FindIForKey(KEY_t key) const
Definition: cArraySort.h:68
bool RemoveKey(TYPE_KEY key)
Definition: cArraySort.h:124
ITERATE_t Add(TYPE_ARG pNew)
Definition: cArraySort.h:186
Definition: cLocker.h:72
static bool isSingleCreated() noexcept
Definition: cSingleton.h:70
static cThreadMgr &__stdcall I()
Definition: cSingleton.h:199
Definition: cThreadLock.h:55
static THREADID_t GetCurrentId() noexcept
Definition: cThreadLock.h:97
static const THREADID_t k_NULL
Not a valid thread Id.
Definition: cThreadLock.h:64
THREADID_t get_ThreadLockOwner() const
Definition: cThreadLock.h:189
Definition: cThreadLock.h:205
Definition: cThreadMgr.h:16
Definition: cMesh.h:22
UNITTEST2_PREDEF(cQuadtree)
int ITERATE_t
like size_t but signed
Definition: Index.h:28
Definition: cThreadLocalSys.h:30