soui 5.0.0.1
Soui5 Doc
 
Loading...
Searching...
No Matches
SRwLock.cpp
1/*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include <helper/SRwLock.h>
12#include <windows.h>
13
14SNSBEGIN
15
16struct IRwLock {
17 virtual ~IRwLock() {}
18 virtual void LockShared(void) = 0;
19 virtual void UnlockShared(void) = 0;
20 virtual void LockExclusive(void) = 0;
21 virtual void UnlockExclusive(void) = 0;
22};
23
24#ifdef _WIN32
25static bool native_rw_locks_supported = false;
26static bool module_load_attempted = false;
27static HMODULE library = NULL;
28
29typedef void (WINAPI* InitializeSRWLock)(PSRWLOCK);
30
31typedef void (WINAPI* AcquireSRWLockExclusive)(PSRWLOCK);
32typedef void (WINAPI* ReleaseSRWLockExclusive)(PSRWLOCK);
33
34typedef void (WINAPI* AcquireSRWLockShared)(PSRWLOCK);
35typedef void (WINAPI* ReleaseSRWLockShared)(PSRWLOCK);
36
37InitializeSRWLock initialize_srw_lock;
38AcquireSRWLockExclusive acquire_srw_lock_exclusive;
39AcquireSRWLockShared acquire_srw_lock_shared;
40ReleaseSRWLockShared release_srw_lock_shared;
41ReleaseSRWLockExclusive release_srw_lock_exclusive;
42
43static bool LoadModule() {
44 if (module_load_attempted) {
45 return native_rw_locks_supported;
46 }
47 module_load_attempted = true;
48 // Use native implementation if supported (i.e Vista+)
49 library = LoadLibrary(TEXT("Kernel32.dll"));
50 if (!library) {
51 return false;
52 }
53
54 initialize_srw_lock =
55 (InitializeSRWLock)GetProcAddress(library, "InitializeSRWLock");
56
57 acquire_srw_lock_exclusive =
58 (AcquireSRWLockExclusive)GetProcAddress(library,
59 "AcquireSRWLockExclusive");
60 release_srw_lock_exclusive =
61 (ReleaseSRWLockExclusive)GetProcAddress(library,
62 "ReleaseSRWLockExclusive");
63 acquire_srw_lock_shared =
64 (AcquireSRWLockShared)GetProcAddress(library, "AcquireSRWLockShared");
65 release_srw_lock_shared =
66 (ReleaseSRWLockShared)GetProcAddress(library, "ReleaseSRWLockShared");
67
68 if (initialize_srw_lock && acquire_srw_lock_exclusive &&
69 release_srw_lock_exclusive && acquire_srw_lock_shared &&
70 release_srw_lock_shared) {
71 native_rw_locks_supported = true;
72 }
73 return native_rw_locks_supported;
74}
75
76class SRwLockWinXP : public IRwLock
77{
78public:
79 SRwLockWinXP()
80 {
81 m_nReaders = 0;
82 InitializeCriticalSection(&m_csWriter);
83 InitializeCriticalSection(&m_csReader);
84 m_evtReaders = CreateEvent(NULL, TRUE, TRUE, NULL);
85
86 }
87
88 ~SRwLockWinXP()
89 {
90 WaitForSingleObject(m_evtReaders, INFINITE);
91 CloseHandle(m_evtReaders);
92 DeleteCriticalSection(&m_csWriter);
93 DeleteCriticalSection(&m_csReader);
94 }
95
96 void LockShared(void) override
97 {
98 EnterCriticalSection(&m_csWriter);
99 EnterCriticalSection(&m_csReader);
100 if (++m_nReaders == 1)
101 {
102 ::ResetEvent(m_evtReaders);
103 }
104 LeaveCriticalSection(&m_csReader);
105 LeaveCriticalSection(&m_csWriter);
106 }
107
108 void UnlockShared(void) override
109 {
110 EnterCriticalSection(&m_csReader);
111 if (--m_nReaders == 0)
112 {
113 ::SetEvent(m_evtReaders);
114 }
115 LeaveCriticalSection(&m_csReader);
116 }
117
118 void LockExclusive(void) override
119 {
120 EnterCriticalSection(&m_csWriter);
121 WaitForSingleObject(m_evtReaders, INFINITE);
122 }
123
124 void UnlockExclusive(void) override
125 {
126 LeaveCriticalSection(&m_csWriter);
127 }
128
129private:
130 CRITICAL_SECTION m_csWriter;
131 CRITICAL_SECTION m_csReader;
132 int m_nReaders;
133 HANDLE m_evtReaders;
134};
135
136class SRwLockWin7 : public IRwLock {
137 SRWLOCK m_rwlock;
138public:
139 SRwLockWin7() {
140 initialize_srw_lock(&m_rwlock);
141 }
142
143 void LockExclusive() override{
144 acquire_srw_lock_exclusive(&m_rwlock);
145 }
146
147 void UnlockExclusive() override {
148 release_srw_lock_exclusive(&m_rwlock);
149 }
150
151 void LockShared() override {
152 acquire_srw_lock_shared(&m_rwlock);
153 }
154
155 void UnlockShared() override {
156 release_srw_lock_shared(&m_rwlock);
157 }
158};
159#else
160
161class SRwLockPosix : public IRwLock {
162 SRWLOCK m_rwlock;
163public:
164 SRwLockPosix() {
165 InitializeSRWLock(&m_rwlock);
166 }
167 ~SRwLockPosix() {
168 UninitializeSRWLock(&m_rwlock);
169 }
170
171 void LockExclusive() override {
172 AcquireSRWLockExclusive(&m_rwlock);
173 }
174
175 void UnlockExclusive() override {
176 ReleaseSRWLockExclusive(&m_rwlock);
177 }
178
179 void LockShared() override {
180 AcquireSRWLockShared(&m_rwlock);
181 }
182
183 void UnlockShared() override {
184 ReleaseSRWLockShared(&m_rwlock);
185 }
186};
187#endif//_WIN32
188
190{
191#ifdef _WIN32
192 if (LoadModule()) {
193 impl = new SRwLockWin7();
194 }
195 else
196 {
197 impl = new SRwLockWinXP();
198 }
199#else
200 impl = new SRwLockPosix;
201#endif
202}
203
205 delete impl;
206}
207
209{
210 impl->LockExclusive();
211}
212
214{
215 impl->UnlockExclusive();
216}
217
219{
220 impl->LockShared();
221}
222
224{
225 impl->UnlockShared();
226}
227
228
229SNSEND
230
~SRwLock()
Destructor. Destroys the read-write lock.
Definition SRwLock.cpp:204
SRwLock()
Constructor. Initializes a new read-write lock.
Definition SRwLock.cpp:189
void LockShared()
Acquires a shared lock.
Definition SRwLock.cpp:218
void UnlockExclusive()
Releases an exclusive lock.
Definition SRwLock.cpp:213
void UnlockShared()
Releases a shared lock.
Definition SRwLock.cpp:223
void LockExclusive()
Acquires an exclusive lock.
Definition SRwLock.cpp:208