商丘数字城管 HPServer

Thread.h 8.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452
  1. /*
  2. * Copyright: JessMA Open Source (ldcsaa@gmail.com)
  3. *
  4. * Version : 2.3.21
  5. * Author : Bruce Liang
  6. * Website : http://www.jessma.org
  7. * Project : https://github.com/ldcsaa
  8. * Blog : http://www.cnblogs.com/ldcsaa
  9. * Wiki : http://www.oschina.net/p/hp-socket
  10. * QQ Group : 75375912, 44636872
  11. *
  12. * Licensed under the Apache License, Version 2.0 (the "License");
  13. * you may not use this file except in compliance with the License.
  14. * You may obtain a copy of the License at
  15. *
  16. * http://www.apache.org/licenses/LICENSE-2.0
  17. *
  18. * Unless required by applicable law or agreed to in writing, software
  19. * distributed under the License is distributed on an "AS IS" BASIS,
  20. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  21. * See the License for the specific language governing permissions and
  22. * limitations under the License.
  23. */
  24. #pragma once
  25. #include <process.h>
  26. #include "RWLock.h"
  27. #include "STLHelper.h"
  28. template<class T, class P = VOID> class CThread
  29. {
  30. private:
  31. typedef UINT (T::*F)(P*);
  32. public:
  33. BOOL Start(T* pRunner, F pFunc, P* pArg = nullptr, int iPriority = THREAD_PRIORITY_NORMAL, UINT uiStackSize = 0, LPSECURITY_ATTRIBUTES lpThreadAttributes = nullptr)
  34. {
  35. BOOL isOK = TRUE;
  36. if(!IsRunning())
  37. {
  38. Release();
  39. m_pRunner = pRunner;
  40. m_pFunc = pFunc;
  41. m_pArg = pArg;
  42. if(iPriority == THREAD_PRIORITY_NORMAL)
  43. m_hThread = (HANDLE)_beginthreadex(lpThreadAttributes, uiStackSize, ThreadProc, (LPVOID)this, 0, &m_uiThreadID);
  44. else
  45. {
  46. m_hThread = (HANDLE)_beginthreadex(lpThreadAttributes, uiStackSize, ThreadProc, (LPVOID)this, CREATE_SUSPENDED, &m_uiThreadID);
  47. if(IsValid())
  48. {
  49. ::SetThreadPriority(m_hThread, iPriority);
  50. ::ResumeThread(m_hThread);
  51. }
  52. }
  53. if(!IsValid())
  54. {
  55. ::SetLastError(ERROR_CREATE_FAILED);
  56. isOK = FALSE;
  57. }
  58. }
  59. else
  60. {
  61. ::SetLastError(ERROR_INVALID_STATE);
  62. isOK = FALSE;
  63. }
  64. return isOK;
  65. }
  66. BOOL Join(BOOL bWithMessageLoop = FALSE, DWORD dwMilliseconds = INFINITE)
  67. {
  68. BOOL isOK = bWithMessageLoop ?
  69. ::MsgWaitForSingleObject(m_hThread, dwMilliseconds) :
  70. ::WaitForSingleObject(m_hThread, dwMilliseconds) == WAIT_OBJECT_0 ;
  71. Release();
  72. return isOK;
  73. }
  74. BOOL IsRunning()
  75. {
  76. if(!IsValid())
  77. return FALSE;
  78. DWORD dwExitCode;
  79. if(GetExitCode(&dwExitCode))
  80. return dwExitCode == STILL_ACTIVE;
  81. return FALSE;
  82. }
  83. VOID Release()
  84. {
  85. if(IsValid())
  86. {
  87. ::CloseHandle(m_hThread);
  88. Reset();
  89. }
  90. }
  91. HANDLE Detatch()
  92. {
  93. HANDLE h = m_hThread;
  94. Reset();
  95. return h;
  96. }
  97. BOOL Terminate (DWORD dwExitCode) {return ::TerminateThread(m_hThread, dwExitCode);}
  98. BOOL GetExitCode (LPDWORD lpExitCode) {return ::GetExitCodeThread(m_hThread, lpExitCode);}
  99. DWORD Suspend () {return ::SuspendThread(m_hThread);}
  100. DWORD Resume () {return ::ResumeThread(m_hThread);}
  101. BOOL IsValid () {return m_hThread != nullptr;}
  102. T* GetRunner () {return m_pRunner;}
  103. F GetFunc () {return m_pFunc;}
  104. P* GetArg () {return m_pArg;}
  105. DWORD GetThreadID () {return m_uiThreadID;}
  106. HANDLE& GetThreadHandle () {return m_hThread;}
  107. const HANDLE& GetThreadHandle () const {return m_hThread;}
  108. public:
  109. CThread()
  110. {
  111. Reset();
  112. }
  113. virtual ~CThread()
  114. {
  115. Release();
  116. }
  117. private:
  118. static UINT WINAPI ThreadProc(LPVOID pv)
  119. {
  120. CThread* pThis = (CThread*)pv;
  121. return ((pThis->m_pRunner)->*(pThis->m_pFunc))(pThis->m_pArg);
  122. }
  123. void Reset()
  124. {
  125. m_uiThreadID = 0;
  126. m_hThread = nullptr;
  127. m_pRunner = nullptr;
  128. m_pFunc = nullptr;
  129. m_pArg = nullptr;
  130. }
  131. private:
  132. UINT m_uiThreadID;
  133. HANDLE m_hThread;
  134. T* m_pRunner;
  135. F m_pFunc;
  136. P* m_pArg;
  137. DECLARE_NO_COPY_CLASS(CThread)
  138. };
  139. template<class T, typename construct_param_type = void*> class CTlsObj
  140. {
  141. typedef unordered_map<DWORD, T*> TLocalMap;
  142. typedef typename TLocalMap::iterator TLocalMapI;
  143. typedef typename TLocalMap::const_iterator TLocalMapCI;
  144. public:
  145. T* TryGet()
  146. {
  147. T* pValue = nullptr;
  148. {
  149. CReadLock locallock(m_lock);
  150. TLocalMapCI it = m_map.find(::GetCurrentThreadId());
  151. if(it != m_map.end())
  152. pValue = it->second;
  153. }
  154. return pValue;
  155. }
  156. T* Get()
  157. {
  158. T* pValue = TryGet();
  159. if(pValue == nullptr)
  160. {
  161. pValue = Construct();
  162. CWriteLock locallock(m_lock);
  163. m_map[::GetCurrentThreadId()] = pValue;
  164. }
  165. return pValue;
  166. }
  167. T& GetRef()
  168. {
  169. return *Get();
  170. }
  171. T* Get(construct_param_type& construct_param)
  172. {
  173. T* pValue = TryGet();
  174. if(pValue == nullptr)
  175. {
  176. pValue = ConstructWithParam(construct_param);
  177. CWriteLock locallock(m_lock);
  178. m_map[::GetCurrentThreadId()] = pValue;
  179. }
  180. return pValue;
  181. }
  182. T& GetRef(construct_param_type& construct_param)
  183. {
  184. return *Get(construct_param);
  185. }
  186. T* SetNewAndGetOld(T* pValue)
  187. {
  188. T* pOldValue = TryGet();
  189. if(pValue != pOldValue)
  190. {
  191. if(pValue == nullptr)
  192. DoRemove();
  193. else
  194. {
  195. CWriteLock locallock(m_lock);
  196. m_map[::GetCurrentThreadId()] = pValue;
  197. }
  198. }
  199. return pOldValue;
  200. }
  201. void Set(T* pValue)
  202. {
  203. T* pOldValue = SetNewAndGetOld(pValue);
  204. if(pValue != pOldValue)
  205. DoDelete(pOldValue);
  206. }
  207. void Remove()
  208. {
  209. T* pValue = TryGet();
  210. if(pValue != nullptr)
  211. {
  212. DoDelete(pValue);
  213. DoRemove();
  214. }
  215. }
  216. void Clear()
  217. {
  218. CWriteLock locallock(m_lock);
  219. if(!IsEmpty())
  220. {
  221. for(TLocalMapCI it = m_map.begin(), end = m_map.end(); it != end; ++it)
  222. DoDelete(it->second);
  223. m_map.clear();
  224. }
  225. }
  226. TLocalMap& GetLocalMap() {return m_map;}
  227. const TLocalMap& GetLocalMap() const {return m_map;}
  228. CTlsObj& operator = (T* p) {Set(p); return *this;}
  229. T* operator -> () {return Get();}
  230. const T* operator -> () const {return Get();}
  231. T& operator * () {return GetRef();}
  232. const T& operator * () const {return GetRef();}
  233. size_t Size () const {return m_map.size();}
  234. bool IsEmpty() const {return m_map.empty();}
  235. public:
  236. CTlsObj()
  237. {
  238. }
  239. CTlsObj(T* pValue)
  240. {
  241. Set(pValue);
  242. }
  243. ~CTlsObj()
  244. {
  245. Clear();
  246. }
  247. private:
  248. inline void DoRemove()
  249. {
  250. CWriteLock locallock(m_lock);
  251. m_map.erase(::GetCurrentThreadId());
  252. }
  253. static inline void DoDelete(T* pValue)
  254. {
  255. if(pValue != nullptr)
  256. delete pValue;
  257. }
  258. static inline T* Construct()
  259. {
  260. return new T;
  261. }
  262. static inline T* ConstructWithParam(construct_param_type& construct_param)
  263. {
  264. return new T(construct_param);
  265. }
  266. private:
  267. CSimpleRWLock m_lock;
  268. TLocalMap m_map;
  269. DECLARE_NO_COPY_CLASS(CTlsObj)
  270. };
  271. template<class T> class CTlsSimple
  272. {
  273. typedef unordered_map<DWORD, T> TLocalMap;
  274. typedef typename TLocalMap::iterator TLocalMapI;
  275. typedef typename TLocalMap::const_iterator TLocalMapCI;
  276. static const T DEFAULT = (T)(0);
  277. public:
  278. BOOL TryGet(T& tValue)
  279. {
  280. BOOL isOK = FALSE;
  281. {
  282. CReadLock locallock(m_lock);
  283. TLocalMapCI it = m_map.find(::GetCurrentThreadId());
  284. if(it != m_map.end())
  285. {
  286. tValue = it->second;
  287. isOK = TRUE;
  288. }
  289. }
  290. return isOK;
  291. }
  292. T Get(T tDefault = DEFAULT)
  293. {
  294. T tValue;
  295. if(TryGet(tValue))
  296. return tValue;
  297. Set(tDefault);
  298. return tDefault;
  299. }
  300. T SetNewAndGetOld(T tValue)
  301. {
  302. T tOldValue;
  303. if(!TryGet(tOldValue))
  304. tOldValue = DEFAULT;
  305. else if(tValue != tOldValue)
  306. Set(tValue);
  307. return tOldValue;
  308. }
  309. void Set(T tValue)
  310. {
  311. CWriteLock locallock(m_lock);
  312. m_map[::GetCurrentThreadId()] = tValue;
  313. }
  314. void Remove()
  315. {
  316. T tValue;
  317. if(TryGet(tValue))
  318. {
  319. CWriteLock locallock(m_lock);
  320. m_map.erase(::GetCurrentThreadId());
  321. }
  322. }
  323. void Clear()
  324. {
  325. CWriteLock locallock(m_lock);
  326. if(!IsEmpty())
  327. m_map.clear();
  328. }
  329. TLocalMap& GetLocalMap() {return m_map;}
  330. const TLocalMap& GetLocalMap() const {return m_map;}
  331. CTlsSimple& operator = (T t) {Set(t); return *this;}
  332. BOOL operator == (T t) {return Get() == t;}
  333. BOOL operator != (T t) {return Get() != t;}
  334. BOOL operator >= (T t) {return Get() >= t;}
  335. BOOL operator <= (T t) {return Get() <= t;}
  336. BOOL operator > (T t) {return Get() > t;}
  337. BOOL operator < (T t) {return Get() < t;}
  338. size_t Size () const {return m_map.size();}
  339. bool IsEmpty() const {return m_map.empty();}
  340. public:
  341. CTlsSimple()
  342. {
  343. }
  344. CTlsSimple(T tValue)
  345. {
  346. Set(tValue);
  347. }
  348. ~CTlsSimple()
  349. {
  350. Clear();
  351. }
  352. DECLARE_NO_COPY_CLASS(CTlsSimple)
  353. private:
  354. CSimpleRWLock m_lock;
  355. TLocalMap m_map;
  356. };