TNB Library
TnbSync.h
[詳解]
1#pragma once
11#include "TnbException.h"
12#include "TnbTickCount.h"
13
14
15
16//T-TestCaseコードカバレッジDisable
17#pragma comment(user,"T-Coverage Disable")
18
19
20
21#include <malloc.h>
22
23
24
25//TNB Library
26namespace TNB
27{
28
29
30
40{
42 virtual ~ISynchronized(void) {}
43
50 virtual bool Lock(DWORD dwTime = INFINITE) const = 0;
51
53 virtual void Unlock(void) const = 0;
54};
55
56
57
67{
68public:
69
74 virtual HANDLE GetHandle(void) const = 0;
75
80 operator HANDLE(void) const
81 {
82 return GetHandle();
83 }
84
91 virtual bool Lock(DWORD dwTime = INFINITE) const
92 {
93 HANDLE h = GetHandle();
94 if ( h != NULL )
95 {
96 DWORD dwRc = ::WaitForSingleObject(h, dwTime);
97 ASSERTLIB(dwRc != WAIT_FAILED);
98 if ( dwRc == WAIT_OBJECT_0 )
99 {
100 return true;//成功した
101 }
102 }
103 return false;
104 }
105};
106
107
125{
126public:
127
130 {
131 ::InitializeCriticalSection(&m_cs);
132 }
133
135 virtual ~CSyncSection(void)
136 {
137 ::DeleteCriticalSection(&m_cs);
138 }
139
148 virtual bool Lock(DWORD dwTime = INFINITE) const
149 {
150 ::EnterCriticalSection(&m_cs);
151 return true;
152 }
153
155 virtual void Unlock(void) const
156 {
157 ::LeaveCriticalSection(&m_cs);
158 }
159
160private:
161 mutable CRITICAL_SECTION m_cs;
162 friend class CSyncSectionEx;
163};
164
165
166
188{
189 DEFSUPER(CSyncSection);
190public:
191
193 CSyncSectionEx(void) : _super(), m_hModule(NULL), m_pTryEntryCs(NULL)
194 {
195 }
196
198 virtual ~CSyncSectionEx(void)
199 {
200 if ( m_hModule != NULL )
201 {
202 ::FreeLibrary(m_hModule);
203 m_hModule = NULL;
204 }
205 }
206
213 virtual bool Lock(DWORD dwTime = INFINITE) const
214 {
215 if ( dwTime == INFINITE )
216 {
217 return _super::Lock(dwTime);
218 }
219 if ( m_hModule == NULL )
220 {
221 m_hModule = ::LoadLibraryA("kernel32.dll");
222 m_pTryEntryCs = reinterpret_cast<P_TryEntryCs>(::GetProcAddressA(m_hModule, "TryEnterCriticalSection"));
223 }
224 if ( m_pTryEntryCs == NULL )
225 {
226 ASSERT0(false, "CSyncSectionEx::Lock()",
227 "API 'TryEnterCriticalSection()' が見つかりません。\nOS がNT4.0以降でない可能性があります。");
228 return false;
229 }
230 if ( dwTime == 0 )
231 {
232 return !! m_pTryEntryCs(&m_cs); //TryEntryCriticalSection実行
233 }
234 CTickCount tick;
235 while ( ! tick.IsPassed(dwTime) )
236 {
237 if ( m_pTryEntryCs(&m_cs) ) //TryEntryCriticalSection実行
238 {
239 return true;
240 }
241 ::Sleep(1);
242 }
243 return false;
244 }
245
246private:
247 typedef DWORD (WINAPI* P_TryEntryCs)(LPCRITICAL_SECTION);
248 mutable P_TryEntryCs m_pTryEntryCs;
249 mutable HMODULE m_hModule;
250};
251
252
253
273{
274 DEFSUPER(CAbstractSyncHandle);
275public:
276
283 explicit CSyncMutex(bool boIsLock = false, LPCTSTR lpszName = NULL) : _super()
284 {
285 m_hMutex = ::CreateMutex(NULL, boIsLock, lpszName);
286 DWORD r = ::GetLastError();
287 if ( r != 0 && r != 0xB7 )
288 {
289 _GetLastError("CreateMutex");
290 }
291 ASSERT0(
292 m_hMutex != NULL,
293 "CSyncMutex::CSyncMutex()",
294 "Mutexが初期化できませんした。"
295 );
296 if ( m_hMutex == NULL )
297 {
299 }
300 }
301
307 explicit CSyncMutex(HANDLE hMutex) : _super()
308 {
309 m_hMutex = hMutex;
310 if ( m_hMutex == NULL )
311 {
313 }
314 }
315
317 virtual ~CSyncMutex(void)
318 {
319 if ( m_hMutex != NULL )
320 {
321 ::ReleaseMutex(m_hMutex);
322 ::CloseHandle(m_hMutex);
323 }
324 }
325
327 virtual void Unlock(void) const
328 {
329 if ( m_hMutex != NULL )
330 {
331 ::ReleaseMutex(m_hMutex);
332 }
333 }
334
339 virtual HANDLE GetHandle(void) const
340 {
341 return m_hMutex;
342 }
343
344private:
345 HANDLE m_hMutex;
346};
347
348
349
370{
371 DEFSUPER(CAbstractSyncHandle);
372public:
373
382 explicit CSyncSemaphore(LPCTSTR lpszName = NULL, int iMaximumCount = 1) : _super()
383 {
384 m_hSema = ::CreateSemaphore(NULL, iMaximumCount, iMaximumCount, lpszName);
385 ASSERT0(
386 m_hSema != NULL,
387 "CSyncSemaphore::CSyncSemaphore()",
388 "Semaphoreが初期化できませんした。"
389 );
390 if ( m_hSema == NULL )
391 {
393 }
394 }
395
401 explicit CSyncSemaphore(HANDLE hSema) : _super()
402 {
403 m_hSema = hSema;
404 if ( m_hSema == NULL )
405 {
407 }
408 }
409
411 virtual ~CSyncSemaphore(void)
412 {
413 if ( m_hSema != NULL )
414 {
415 ::ReleaseSemaphore(m_hSema, 1, NULL);
416 ::CloseHandle(m_hSema);
417 }
418 }
419
421 virtual void Unlock(void) const
422 {
423 if ( m_hSema != NULL )
424 {
425 ::ReleaseSemaphore(m_hSema, 1, NULL);
426 }
427 }
428
434 LONG Unlock(LONG lCount) const
435 {
436 LONG l = 0;
437 if ( m_hSema != NULL )
438 {
439 ::ReleaseSemaphore(m_hSema, lCount, &l);
440 }
441 return l;
442 }
443
448 virtual HANDLE GetHandle(void) const
449 {
450 return m_hSema;
451 }
452
453private:
454 HANDLE m_hSema;
455};
456
457
458
480{
481 DEFSUPER(CAbstractSyncHandle);
482public:
483
492 explicit
493 CSyncEvent(bool boIsManualReset = false, bool boIsLock = false, LPCTSTR lpszName = NULL) : _super()
494 {
495 m_hEvent = ::CreateEvent(NULL, boIsManualReset, ! boIsLock, lpszName);
496 ASSERT0(
497 m_hEvent != NULL,
498 "CSyncEvent::CSyncEvent()",
499 "Eventが初期化できませんした。名前に問題がある可能性が有ります。"
500 );
501 if ( m_hEvent == NULL )
502 {
504 }
505 }
506
512 explicit CSyncEvent(HANDLE hEvent) : _super()
513 {
514 m_hEvent = hEvent;
515 if ( m_hEvent == NULL )
516 {
518 }
519 }
520
522 virtual ~CSyncEvent(void)
523 {
524 if ( m_hEvent != NULL )
525 {
526 ::SetEvent(m_hEvent);
527 ::CloseHandle(m_hEvent);
528 }
529 }
530
532 virtual void Unlock(void) const
533 {
534 if ( m_hEvent != NULL )
535 {
536 ::SetEvent(m_hEvent);
537 }
538 }
539
544 void ToLock(void)
545 {
546 if ( m_hEvent != NULL )
547 {
548 ::ResetEvent(m_hEvent);
549 }
550 }
551
556 void Pulse(void)
557 {
558 if ( m_hEvent != NULL )
559 {
560 ::PulseEvent(m_hEvent);
561 }
562 }
563
568 virtual HANDLE GetHandle(void) const
569 {
570 return m_hEvent;
571 }
572
573private:
574 HANDLE m_hEvent;
575};
576
577
578
594{
595public:
596
601 CSyncCounter(LONG lMax=1) : m_lCounter(0), m_lMax(lMax)
602 {
603 }
604
606 virtual ~CSyncCounter(void)
607 {
608 ASSERT0(
609 m_lCounter == 0,
610 "CSyncCounter::~CSyncCounter()",
611 "内部ロックカウントの数が合いません。\n\tLock()とUnlock()回数があっていない可能性が有ります。"
612 );
613 }
614
621 virtual bool Lock(DWORD dwTime = INFINITE) const
622 {
623 if ( dwTime == 0 )
624 {
625 return m_check();
626 }
627 else if ( dwTime == INFINITE )
628 {
629 while ( true )
630 {
631 if ( m_check() )
632 {
633 return true;
634 }
635 ::Sleep(1);
636 }
637 }
638 else
639 {
640 CTickCount tick;
641 while ( ! tick.IsPassed(dwTime) )
642 {
643 if ( m_check() )
644 {
645 return true;
646 }
647 ::Sleep(1);
648 }
649 }
650 return false;
651 }
652
654 virtual void Unlock(void) const
655 {
656 if ( ::InterlockedDecrement(&m_lCounter) < 0 )
657 {
658 ASSERT0(false, "CSyncCounter::Unlock()", "Unlock()回数がLock()よりも多いです。");
659 ::InterlockedExchange(&m_lCounter, 0);
660 }
661 }
662
663private:
664 mutable LONG m_lCounter;
665 LONG m_lMax;
666
668 bool m_check(void) const
669 {
670 if ( ::InterlockedIncrement(&m_lCounter) <= m_lMax )
671 {
672 return true;
673 }
674 ::InterlockedDecrement(&m_lCounter);
675 return false;
676 }
677};
678
679
680
692{
693public:
694
696 CSyncDummy(void) {}
697
699 virtual ~CSyncDummy(void) {}
700
706 virtual bool Lock(DWORD dwTime = INFINITE) const
707 {
708 return true;
709 }
710
712 virtual void Unlock(void) const {}
713};
714
715
716
732{
733public:
734
740 explicit CExclusive(const ISynchronized* P) : m_psyncObj(P)
741 {
742 if ( m_psyncObj == NULL )
743 {
744 throw CNullPointerException();
745 }
746 m_psyncObj->Lock();
747 }
748
751 {
752 m_psyncObj->Unlock();
753 }
754
755private:
756 const ISynchronized * m_psyncObj;
757};
758
759
760
788#define EXCLUSIVE(CLS) CExclusive _cExclus_(CLS);
789
790
802#define EXCLUSIVE_(CLS) \
803 TRACE3("%s(%d):[%d] Lock要求\n",_T(__FILE__),__LINE__,::GetCurrentThreadId()); \
804 CExclusive _cExclus_(CLS); \
805 TRACE3("%s(%d):[%d] Lock成功\n",_T(__FILE__),__LINE__,::GetCurrentThreadId());
806
807
808
820#define EXCLUSIVE2(CLS1,CLS2) CExclusive _cExclus1_(CLS1); CExclusive _cExclus2_(CLS2);
821
822
823
835#define EXCLUSIVE2_(CLS1,CLS2) \
836 TRACE3("%s(%d):[%d] Lock要求\n",_T(__FILE__),__LINE__,::GetCurrentThreadId()); \
837 CExclusive _cExclus1_(CLS1); CExclusive _cExclus2_(CLS2); \
838 TRACE3("%s(%d):[%d] Lock成功\n",_T(__FILE__),__LINE__,::GetCurrentThreadId());
839
840
841
855{
856 DEFSUPER(CExclusive);
857public:
858
864 explicit CExclusiveEx(const ISynchronized* P) : _super(P), m_iChkCnt(0)
865 {
866 }
867
873 operator int(void)
874 {
875 return m_iChkCnt++;
876 }
877
878private:
879 int m_iChkCnt;
880};
881
882
883
912#define SYNCBLOCK(CLS) if (false); else for ( CExclusiveEx _cExclusEx_(CLS); _cExclusEx_ == 0; )
913
914
915
916}; // TNB
917
918
919
920//T-TestCaseコードカバレッジEnable
921#pragma comment(user,"T-Coverage Enable")
例外状態管理関係のヘッダ
経過時間管理関係のヘッダ
HANDLE型排他抽象クラス
Definition: TnbSync.h:67
virtual bool Lock(DWORD dwTime=INFINITE) const
[排他] ロック
Definition: TnbSync.h:91
virtual HANDLE GetHandle(void) const =0
[取得] ハンドル取得
[ETC] コピー不可能スーパークラス.
Definition: TnbDef.h:599
簡易排他制御クラス
Definition: TnbSync.h:855
CExclusiveEx(const ISynchronized *P)
コンストラクタ
Definition: TnbSync.h:864
簡易排他制御クラス
Definition: TnbSync.h:732
CExclusive(const ISynchronized *P)
コンストラクタ
Definition: TnbSync.h:740
~CExclusive(void)
デストラクタ
Definition: TnbSync.h:750
パラメータ不正例外
Definition: TnbException.h:159
NULLポインタ例外
Definition: TnbException.h:172
カウンタ式排他クラス
Definition: TnbSync.h:594
virtual ~CSyncCounter(void)
デストラクタ
Definition: TnbSync.h:606
virtual bool Lock(DWORD dwTime=INFINITE) const
[排他] ロック
Definition: TnbSync.h:621
CSyncCounter(LONG lMax=1)
コンストラクタ
Definition: TnbSync.h:601
virtual void Unlock(void) const
[排他] アンロック
Definition: TnbSync.h:654
排他管理ダミークラス
Definition: TnbSync.h:692
CSyncDummy(void)
コンストラクタ
Definition: TnbSync.h:696
virtual bool Lock(DWORD dwTime=INFINITE) const
[排他] ロック
Definition: TnbSync.h:706
virtual void Unlock(void) const
[排他] アンロック
Definition: TnbSync.h:712
virtual ~CSyncDummy(void)
デストラクタ
Definition: TnbSync.h:699
Event排他管理クラス
Definition: TnbSync.h:480
CSyncEvent(bool boIsManualReset=false, bool boIsLock=false, LPCTSTR lpszName=NULL)
コンストラクタ
Definition: TnbSync.h:493
void ToLock(void)
[排他] ロック状態にする
Definition: TnbSync.h:544
CSyncEvent(HANDLE hEvent)
コンストラクタ
Definition: TnbSync.h:512
virtual ~CSyncEvent(void)
デストラクタ
Definition: TnbSync.h:522
void Pulse(void)
[排他] ロック状態にする
Definition: TnbSync.h:556
virtual HANDLE GetHandle(void) const
[取得] Mutexハンドル取得
Definition: TnbSync.h:568
virtual void Unlock(void) const
[排他] アンロック
Definition: TnbSync.h:532
Mutex排他管理クラス
Definition: TnbSync.h:273
CSyncMutex(bool boIsLock=false, LPCTSTR lpszName=NULL)
コンストラクタ
Definition: TnbSync.h:283
virtual ~CSyncMutex(void)
デストラクタ
Definition: TnbSync.h:317
CSyncMutex(HANDLE hMutex)
コンストラクタ
Definition: TnbSync.h:307
virtual HANDLE GetHandle(void) const
[取得] Mutexハンドル取得
Definition: TnbSync.h:339
virtual void Unlock(void) const
[排他] アンロック
Definition: TnbSync.h:327
拡張Section排他管理クラス
Definition: TnbSync.h:188
virtual ~CSyncSectionEx(void)
デストラクタ
Definition: TnbSync.h:198
virtual bool Lock(DWORD dwTime=INFINITE) const
[排他] ロック
Definition: TnbSync.h:213
CSyncSectionEx(void)
コンストラクタ
Definition: TnbSync.h:193
Section排他管理クラス
Definition: TnbSync.h:125
virtual bool Lock(DWORD dwTime=INFINITE) const
[排他] ロック
Definition: TnbSync.h:148
CSyncSection(void)
コンストラクタ
Definition: TnbSync.h:129
virtual ~CSyncSection(void)
デストラクタ
Definition: TnbSync.h:135
virtual void Unlock(void) const
[排他] アンロック
Definition: TnbSync.h:155
Semaphore排他管理クラス
Definition: TnbSync.h:370
CSyncSemaphore(HANDLE hSema)
コンストラクタ
Definition: TnbSync.h:401
CSyncSemaphore(LPCTSTR lpszName=NULL, int iMaximumCount=1)
コンストラクタ
Definition: TnbSync.h:382
virtual HANDLE GetHandle(void) const
[取得] Mutexハンドル取得
Definition: TnbSync.h:448
virtual ~CSyncSemaphore(void)
デストラクタ
Definition: TnbSync.h:411
LONG Unlock(LONG lCount) const
[排他] アンロック
Definition: TnbSync.h:434
virtual void Unlock(void) const
[排他] アンロック
Definition: TnbSync.h:421
経過時間管理クラス
Definition: TnbTickCount.h:57
bool IsPassed(DWORD dwTime) const
[確認] 経過確認.
Definition: TnbTickCount.h:114
TNB Library
Definition: TnbDoxyTitle.txt:2
排他基本インターフェース
Definition: TnbSync.h:40
virtual ~ISynchronized(void)
デストラクタ
Definition: TnbSync.h:42
virtual bool Lock(DWORD dwTime=INFINITE) const =0
[排他] ロック
virtual void Unlock(void) const =0
[排他] アンロック