Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

499 lines
9.6 KiB

  1. //
  2. // cicmutex.h
  3. //
  4. #ifndef CICMUTEX_H
  5. #define CICMUTEX_H
  6. class CCicMutexHelper;
  7. struct CCicMutex
  8. {
  9. public:
  10. BOOL Init(SECURITY_ATTRIBUTES *psa, TCHAR *psz)
  11. {
  12. _hMutex = CreateMutex(psa, FALSE, psz);
  13. Assert(_hMutex);
  14. return _hMutex ? TRUE : FALSE;
  15. }
  16. void Uninit()
  17. {
  18. if (_hMutex)
  19. CloseHandle(_hMutex);
  20. _hMutex = NULL;
  21. return;
  22. }
  23. BOOL Enter()
  24. {
  25. Assert(_hMutex);
  26. DWORD dwWaitResult = WaitForSingleObject(_hMutex, 5000);
  27. if (dwWaitResult == WAIT_OBJECT_0)
  28. {
  29. return TRUE;
  30. }
  31. else if (dwWaitResult == WAIT_ABANDONED)
  32. {
  33. TraceMsg(TF_EVENT, "CicMutex abandoned");
  34. return TRUE;
  35. }
  36. TraceMsg(TF_EVENT, "CicMutex Time Out");
  37. //
  38. // assert here to debug stop.
  39. //
  40. Assert(0);
  41. return FALSE;
  42. }
  43. void Leave()
  44. {
  45. Assert(_hMutex);
  46. ReleaseMutex(_hMutex);
  47. }
  48. private:
  49. HANDLE _hMutex;
  50. };
  51. class CCicMutexHelperStatic
  52. {
  53. public:
  54. void Init(CCicMutex *pcicmutex)
  55. {
  56. _pcicmutex = pcicmutex;
  57. SetIn(FALSE);
  58. }
  59. void Uninit()
  60. {
  61. Assert(!_fIn);
  62. _pcicmutex = NULL;
  63. }
  64. BOOL Enter()
  65. {
  66. BOOL bRet = _pcicmutex->Enter();
  67. SetIn(TRUE);
  68. return bRet;
  69. }
  70. void Leave()
  71. {
  72. SetIn(FALSE);
  73. _pcicmutex->Leave();
  74. }
  75. BOOL Invalid()
  76. {
  77. return _pcicmutex ? TRUE : FALSE;
  78. }
  79. protected:
  80. CCicMutex *_pcicmutex;
  81. #ifdef DEBUG
  82. void SetIn(BOOL fIn) {_fIn = fIn;}
  83. BOOL _fIn;
  84. #else
  85. void SetIn(BOOL fIn) {}
  86. #endif
  87. };
  88. class CCicMutexHelper : public CCicMutexHelperStatic
  89. {
  90. public:
  91. CCicMutexHelper(CCicMutex *pcicmutex = NULL)
  92. {
  93. #ifdef DEBUG
  94. _fIn = FALSE;
  95. #endif
  96. _pcicmutex = NULL;
  97. if (pcicmutex)
  98. Init(pcicmutex);
  99. }
  100. ~CCicMutexHelper()
  101. {
  102. Assert(!_fIn);
  103. }
  104. };
  105. class CCicFileMappingStatic
  106. {
  107. public:
  108. void BaseInit()
  109. {
  110. _pv = NULL;
  111. _hfm = NULL;
  112. }
  113. void Finalize()
  114. {
  115. if (_fUseMutex)
  116. {
  117. Close();
  118. //
  119. // mutexhlp could be invalid if Uninit() was called.
  120. //
  121. if (_mutexhlp.Invalid())
  122. _mutexhlp.Leave();
  123. }
  124. else
  125. {
  126. //
  127. // Close() must be called when client's own mutex is released,
  128. // if _fuseMutex is FALSE.
  129. //
  130. Assert(!_hfm);
  131. }
  132. }
  133. void Init(TCHAR *pszFile, CCicMutex *pmutex)
  134. {
  135. Assert(!_hfm);
  136. Assert(!_pv);
  137. if (pmutex)
  138. _mutexhlp.Init(pmutex);
  139. _pszFile = pszFile;
  140. _fCreated = FALSE;
  141. _fUseMutex = pmutex ? TRUE : FALSE;
  142. }
  143. void Uninit()
  144. {
  145. _mutexhlp.Uninit();
  146. }
  147. void *Open()
  148. {
  149. Assert(!_hfm);
  150. if (!_pszFile)
  151. {
  152. Assert(0);
  153. return NULL;
  154. }
  155. _hfm = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, _pszFile);
  156. if (_hfm == NULL)
  157. return NULL;
  158. return _Map();
  159. }
  160. void *Create(SECURITY_ATTRIBUTES *psa, ULONG cbSize, BOOL *pfAlreadyExists)
  161. {
  162. Assert(!_hfm);
  163. if (!_pszFile)
  164. {
  165. Assert(0);
  166. return NULL;
  167. }
  168. _hfm = CreateFileMapping(INVALID_HANDLE_VALUE, psa, PAGE_READWRITE,
  169. 0, cbSize, _pszFile);
  170. if (pfAlreadyExists != NULL)
  171. {
  172. *pfAlreadyExists = (GetLastError() == ERROR_ALREADY_EXISTS);
  173. }
  174. if (_hfm == NULL)
  175. return NULL;
  176. _fCreated = TRUE;
  177. return _Map();
  178. }
  179. BOOL Flush(UINT cbSize)
  180. {
  181. if (!_pv)
  182. return FALSE;
  183. return FlushViewOfFile(_pv, cbSize);
  184. }
  185. void Close()
  186. {
  187. if (_pv)
  188. UnmapViewOfFile(_pv);
  189. if (_hfm)
  190. CloseHandle(_hfm);
  191. _pv = NULL;
  192. _hfm = NULL;
  193. _fCreated = FALSE;
  194. }
  195. void SetName(TCHAR *psz) {_pszFile = psz;}
  196. BOOL Enter()
  197. {
  198. if (_fUseMutex)
  199. if (!_mutexhlp.Enter())
  200. return FALSE;
  201. return TRUE;
  202. }
  203. void Leave()
  204. {
  205. if (_fUseMutex)
  206. _mutexhlp.Leave();
  207. }
  208. BOOL IsCreated() { return _fCreated; }
  209. private:
  210. void *_Map()
  211. {
  212. Assert(!_pv);
  213. _pv = (void *)MapViewOfFile(_hfm, FILE_MAP_WRITE, 0, 0, 0);
  214. if (!_pv)
  215. {
  216. CloseHandle(_hfm);
  217. _hfm = NULL;
  218. }
  219. return _pv;
  220. }
  221. protected:
  222. TCHAR *_pszFile;
  223. void *_pv;
  224. private:
  225. HANDLE _hfm;
  226. BOOL _fCreated;
  227. BOOL _fUseMutex;
  228. CCicMutexHelperStatic _mutexhlp;
  229. };
  230. class CCicFileMapping : public CCicFileMappingStatic
  231. {
  232. public:
  233. CCicFileMapping(TCHAR *pszFile = NULL, CCicMutex *pmutex = NULL)
  234. {
  235. BaseInit();
  236. Init(pszFile, pmutex );
  237. }
  238. virtual ~CCicFileMapping()
  239. {
  240. Finalize();
  241. }
  242. };
  243. class CCicEvent
  244. {
  245. public:
  246. CCicEvent(TCHAR *psz = NULL)
  247. {
  248. _psz = psz;
  249. _hEvent = NULL;
  250. }
  251. ~CCicEvent()
  252. {
  253. Uninit();
  254. }
  255. BOOL Create(SECURITY_ATTRIBUTES *psa, TCHAR *psz = NULL)
  256. {
  257. if (psz)
  258. {
  259. Assert(!_psz);
  260. _psz = psz;
  261. }
  262. if (!_psz)
  263. {
  264. Assert(0);
  265. return FALSE;
  266. }
  267. Assert(!_hEvent);
  268. _hEvent = CreateEvent(psa, FALSE, FALSE, _psz);
  269. #ifdef DEBUG
  270. TraceMsg(TF_EVENT, "%s CCicEvent::Create %x %s", _szModule, _hEvent, _psz);
  271. #endif
  272. Assert(_hEvent);
  273. return _hEvent ? TRUE : FALSE;
  274. }
  275. BOOL Open(TCHAR *psz = NULL)
  276. {
  277. if (psz)
  278. {
  279. Assert(!_psz);
  280. _psz = psz;
  281. }
  282. Assert(!_hEvent);
  283. Assert(_psz);
  284. _hEvent = OpenEvent(EVENT_ALL_ACCESS, FALSE, _psz);
  285. #ifdef DEBUG
  286. TraceMsg(TF_EVENT, "%s CCicEvent::Open %x %s", _szModule, _hEvent, _psz);
  287. #endif
  288. // Assert(_hEvent);
  289. #ifdef DEBUG
  290. if (!_hEvent)
  291. {
  292. DWORD dwError = GetLastError();
  293. TraceMsg(TF_EVENT, "OpenEvent error = %x %s\r\n", dwError, _psz);
  294. }
  295. #endif
  296. return _hEvent ? TRUE : FALSE;
  297. }
  298. void Uninit()
  299. {
  300. #ifdef DEBUG
  301. TraceMsg(TF_EVENT, "%s CCicEvent::Close %x %s", _szModule, _hEvent, _psz);
  302. #endif
  303. if (_hEvent)
  304. CloseHandle(_hEvent);
  305. _hEvent = NULL;
  306. return;
  307. }
  308. BOOL Wait(DWORD dwMillisecouds)
  309. {
  310. #ifdef DEBUG
  311. TraceMsg(TF_EVENT, "%s CCicEvent::Wait %x %s", _szModule, _hEvent, _psz);
  312. #endif
  313. DWORD dwWaitResult = WaitForSingleObject(_hEvent, dwMillisecouds);
  314. if (dwWaitResult == WAIT_OBJECT_0)
  315. {
  316. return TRUE;
  317. }
  318. #ifdef DEBUG
  319. TraceMsg(TF_EVENT, "%s CCicEvent Time Out", _szModule);
  320. #endif
  321. //
  322. // assert here to debug stop.
  323. //
  324. // Assert(0);
  325. return FALSE;
  326. }
  327. DWORD EventCheck()
  328. {
  329. Assert(_hEvent);
  330. return WaitForSingleObject(_hEvent, 0);
  331. }
  332. DWORD MsgWait(DWORD dwWaitTime, DWORD dwWakeMask, DWORD dwFlags = 0)
  333. {
  334. Assert(_hEvent);
  335. #ifdef DEBUG
  336. TraceMsg(TF_EVENT, "%s CCicEvent::MsgWait %x %s", _szModule, _hEvent, _psz);
  337. #endif
  338. DWORD dwWaitResult;
  339. dwWaitResult = MsgWaitForMultipleObjects(1,
  340. &_hEvent,
  341. FALSE,
  342. dwWaitTime,
  343. dwWakeMask);
  344. #ifdef DEBUG
  345. if (dwWaitResult == WAIT_TIMEOUT)
  346. {
  347. TraceMsg(TF_EVENT, "%s CCicEvent Time Out::timeout val=%d", _szModule, dwWaitTime);
  348. }
  349. #endif
  350. return dwWaitResult;
  351. }
  352. void Set()
  353. {
  354. #ifdef DEBUG
  355. TraceMsg(TF_EVENT, "%s CCicEvent::Set %x %s", _szModule, _hEvent, _psz);
  356. #endif
  357. SetEvent(_hEvent);
  358. }
  359. void Reset()
  360. {
  361. #ifdef DEBUG
  362. TraceMsg(TF_EVENT, "%s CCicEvent::ReSet %x %s", _szModule, _hEvent, _psz);
  363. #endif
  364. ResetEvent(_hEvent);
  365. }
  366. void SetName(TCHAR *psz) {_psz = psz;}
  367. private:
  368. HANDLE _hEvent;
  369. #ifdef DEBUG
  370. TCHAR _szModule[MAX_PATH];
  371. #endif
  372. protected:
  373. TCHAR *_psz;
  374. };
  375. class CCicTimer
  376. {
  377. public:
  378. CCicTimer(DWORD dwMilliSeconds, BOOL fStart = TRUE)
  379. {
  380. _dwTimeOut = dwMilliSeconds / 10;
  381. _dwTimeToWait = (DWORD)(-1);
  382. _dwStartTime = (DWORD)(-1);
  383. if (fStart)
  384. Start();
  385. }
  386. void Start()
  387. {
  388. _dwStartTime = GetTickCount() / 10;
  389. _dwTimeToWait = _dwStartTime + _dwTimeOut;
  390. }
  391. BOOL IsTimerAtZero()
  392. {
  393. DWORD dwNow = GetTickCount() / 10;
  394. if (_dwTimeToWait < dwNow)
  395. return TRUE;
  396. return FALSE;
  397. }
  398. BOOL IsTimerPass(DWORD dwWaitSec)
  399. {
  400. DWORD dwNow = GetTickCount() / 10;
  401. dwWaitSec /= 10;
  402. if (dwNow - _dwStartTime > dwWaitSec)
  403. return TRUE;
  404. return FALSE;
  405. }
  406. private:
  407. DWORD _dwTimeToWait;
  408. DWORD _dwStartTime;
  409. DWORD _dwTimeOut;
  410. };
  411. #endif // CICMUTEX_H