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)
17 SharedMutex::~SharedMutex()
22 void SharedMutex::Release()
24 ::CloseHandle(m_mutex
);
25 ::CloseHandle(m_sharedEvent
);
26 ::CloseHandle(m_exclusiveEvent
);
28 void SharedMutex::Init()
30 m_sharedNum
= m_exclusiveNum
= 0;
31 m_lockType
= LOCK_NONE
;
33 // ´´½¨ÓÃÓÚ±£»¤ÄÚ²¿Êý¾ÝµÄ»¥³âÁ¿
34 m_mutex
= ::CreateMutex(NULL
, FALSE
, NULL
);
35 // ´´½¨ÓÃÓÚͬ²½¹²Ïí·ÃÎÊÏ̵߳Äʼþ£¨ÊÖ¶¯Ê¼þ£©
36 m_sharedEvent
= ::CreateEvent(NULL
, TRUE
, FALSE
, NULL
);
37 // ´´½¨ÓÃÓÚͬ²½¶ÀÕ¼·ÃÎÊÏ̵߳Äʼþ£¨×Ô¶¯Ê¼þ£©
38 m_exclusiveEvent
= ::CreateEvent(NULL
, FALSE
, FALSE
, NULL
);
42 bool SharedMutex::AcquireShared(DWORD waitTime
)
44 ::WaitForSingleObject(m_mutex
, INFINITE
);
46 if (m_lockType
== LOCK_EXCLUSIVE
) {
47 DWORD retCode
= ::SignalObjectAndWait(m_mutex
, m_sharedEvent
, waitTime
, FALSE
);
48 if (retCode
== WAIT_OBJECT_0
) {
51 if (retCode
== WAIT_TIMEOUT
)
52 ::SetLastError(WAIT_TIMEOUT
);
56 m_lockType
= LOCK_SHARED
;
57 ::ReleaseMutex(m_mutex
);
62 void SharedMutex::ReleaseShared()
64 //assert(m_lockType == LOCK_SHARED);
65 ::WaitForSingleObject(m_mutex
, INFINITE
);
67 if (m_sharedNum
== 0) {
68 if (m_exclusiveNum
> 0) {
69 // »½ÐÑÒ»¸ö¶ÀÕ¼·ÃÎÊÏß³Ì
70 m_lockType
= LOCK_EXCLUSIVE
;
71 ::SetEvent(m_exclusiveEvent
);
74 m_lockType
= LOCK_NONE
;
77 ::ReleaseMutex(m_mutex
);
81 bool SharedMutex::AcquireExclusive(DWORD waitTime
)
84 ::WaitForSingleObject(m_mutex
, INFINITE
);
86 if (m_lockType
!= LOCK_NONE
) {
87 DWORD retCode
= ::SignalObjectAndWait(m_mutex
, m_exclusiveEvent
, waitTime
, FALSE
);
88 if (retCode
== WAIT_OBJECT_0
) {
91 if (retCode
== WAIT_TIMEOUT
)
92 ::SetLastError(WAIT_TIMEOUT
);
96 m_lockType
= LOCK_EXCLUSIVE
;
97 ::ReleaseMutex(m_mutex
);
102 void SharedMutex::ReleaseExclusive()
104 // assert(m_lockType == LOCK_EXCLUSIVE);
105 ::WaitForSingleObject(m_mutex
, INFINITE
);
108 if (m_exclusiveNum
> 0) {
109 // »½ÐÑÒ»¸ö¶ÀÕ¼·ÃÎÊÏß³Ì
110 ::SetEvent(m_exclusiveEvent
);
111 } else if (m_sharedNum
> 0) {
112 // »½Ðѵ±Ç°ËùÓй²Ïí·ÃÎÊÏß³Ì
113 m_lockType
= LOCK_SHARED
;
114 ::PulseEvent(m_sharedEvent
);
117 m_lockType
= LOCK_NONE
;
119 ::ReleaseMutex(m_mutex
);