3 * @Author Tu Yongce <yongce (at) 126 (dot) com>
9 #include "SharedMutex.h"
12 SharedMutex::SharedMutex(): m_sharedNum(0), m_exclusiveNum(0), m_lockType(LOCK_NONE
), m_mutex(0), m_sharedEvent(0),m_exclusiveEvent(0)
16 SharedMutex::~SharedMutex()
20 void SharedMutex::Release()
24 ::CloseHandle(m_mutex
);
29 ::CloseHandle(m_sharedEvent
);
34 ::CloseHandle(m_exclusiveEvent
);
35 m_exclusiveEvent
= NULL
;
38 void SharedMutex::Init()
40 m_sharedNum
= m_exclusiveNum
= 0;
41 m_lockType
= LOCK_NONE
;
43 // ´´½¨ÓÃÓÚ±£»¤ÄÚ²¿Êý¾ÝµÄ»¥³âÁ¿
44 m_mutex
= ::CreateMutex(NULL
, FALSE
, NULL
);
45 // ´´½¨ÓÃÓÚͬ²½¹²Ïí·ÃÎÊÏ̵߳Äʼþ£¨ÊÖ¶¯Ê¼þ£©
46 m_sharedEvent
= ::CreateEvent(NULL
, TRUE
, FALSE
, NULL
);
47 // ´´½¨ÓÃÓÚͬ²½¶ÀÕ¼·ÃÎÊÏ̵߳Äʼþ£¨×Ô¶¯Ê¼þ£©
48 m_exclusiveEvent
= ::CreateEvent(NULL
, FALSE
, FALSE
, NULL
);
52 bool SharedMutex::AcquireShared(DWORD waitTime
)
54 ::WaitForSingleObject(m_mutex
, INFINITE
);
56 if (m_lockType
== LOCK_EXCLUSIVE
) {
57 DWORD retCode
= ::SignalObjectAndWait(m_mutex
, m_sharedEvent
, waitTime
, FALSE
);
58 if (retCode
== WAIT_OBJECT_0
) {
61 if (retCode
== WAIT_TIMEOUT
)
62 ::SetLastError(WAIT_TIMEOUT
);
66 m_lockType
= LOCK_SHARED
;
67 ::ReleaseMutex(m_mutex
);
72 void SharedMutex::ReleaseShared()
74 //assert(m_lockType == LOCK_SHARED);
75 ::WaitForSingleObject(m_mutex
, INFINITE
);
77 if (m_sharedNum
== 0) {
78 if (m_exclusiveNum
> 0) {
79 // »½ÐÑÒ»¸ö¶ÀÕ¼·ÃÎÊÏß³Ì
80 m_lockType
= LOCK_EXCLUSIVE
;
81 ::SetEvent(m_exclusiveEvent
);
84 m_lockType
= LOCK_NONE
;
87 ::ReleaseMutex(m_mutex
);
91 bool SharedMutex::AcquireExclusive(DWORD waitTime
)
94 ::WaitForSingleObject(m_mutex
, INFINITE
);
96 if (m_lockType
!= LOCK_NONE
) {
97 DWORD retCode
= ::SignalObjectAndWait(m_mutex
, m_exclusiveEvent
, waitTime
, FALSE
);
98 if (retCode
== WAIT_OBJECT_0
) {
101 if (retCode
== WAIT_TIMEOUT
)
102 ::SetLastError(WAIT_TIMEOUT
);
106 m_lockType
= LOCK_EXCLUSIVE
;
107 ::ReleaseMutex(m_mutex
);
112 void SharedMutex::ReleaseExclusive()
114 // assert(m_lockType == LOCK_EXCLUSIVE);
115 ::WaitForSingleObject(m_mutex
, INFINITE
);
118 if (m_exclusiveNum
> 0) {
119 // »½ÐÑÒ»¸ö¶ÀÕ¼·ÃÎÊÏß³Ì
120 ::SetEvent(m_exclusiveEvent
);
121 } else if (m_sharedNum
> 0) {
122 // »½Ðѵ±Ç°ËùÓй²Ïí·ÃÎÊÏß³Ì
123 m_lockType
= LOCK_SHARED
;
124 ::PulseEvent(m_sharedEvent
);
127 m_lockType
= LOCK_NONE
;
129 ::ReleaseMutex(m_mutex
);