1 //
2 // RWLock.h
3 //
4 // Library: Foundation
5 // Package: Threading
6 // Module: RWLock
7 //
8 // Definition of the RWLock class.
9 //
10 // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
11 // and Contributors.
12 //
13 // SPDX-License-Identifier: BSL-1.0
14 //
15
16
17 #ifndef Foundation_RWLock_INCLUDED
18 #define Foundation_RWLock_INCLUDED
19
20
21 #include "Poco/Foundation.h"
22 #include "Poco/Exception.h"
23
24
25 #if defined(POCO_OS_FAMILY_WINDOWS)
26 #if defined(_WIN32_WCE)
27 #include "Poco/RWLock_WINCE.h"
28 #else
29 #include "Poco/RWLock_WIN32.h"
30 #endif
31 #elif POCO_OS == POCO_OS_ANDROID
32 #include "Poco/RWLock_Android.h"
33 #elif defined(POCO_VXWORKS)
34 #include "Poco/RWLock_VX.h"
35 #else
36 #include "Poco/RWLock_POSIX.h"
37 #endif
38
39
40 namespace Poco {
41
42
43 class ScopedRWLock;
44 class ScopedReadRWLock;
45 class ScopedWriteRWLock;
46
47
48 class Foundation_API RWLock: private RWLockImpl
49 /// A reader writer lock allows multiple concurrent
50 /// readers or one exclusive writer.
51 {
52 public:
53 using ScopedLock = ScopedRWLock;
54 using ScopedReadLock = ScopedReadRWLock;
55 using ScopedWriteLock = ScopedWriteRWLock;
56
57 RWLock();
58 /// Creates the Reader/Writer lock.
59
60 ~RWLock();
61 /// Destroys the Reader/Writer lock.
62
63 void readLock();
64 /// Acquires a read lock. If another thread currently holds a write lock,
65 /// waits until the write lock is released.
66
67 bool tryReadLock();
68 /// Tries to acquire a read lock. Immediately returns true if successful, or
69 /// false if another thread currently holds a write lock.
70
71 void writeLock();
72 /// Acquires a write lock. If one or more other threads currently hold
73 /// locks, waits until all locks are released. The results are undefined
74 /// if the same thread already holds a read or write lock
75
76 bool tryWriteLock();
77 /// Tries to acquire a write lock. Immediately returns true if successful,
78 /// or false if one or more other threads currently hold
79 /// locks. The result is undefined if the same thread already
80 /// holds a read or write lock.
81
82 void unlock();
83 /// Releases the read or write lock.
84
85 private:
86 RWLock(const RWLock&);
87 RWLock& operator = (const RWLock&);
88 };
89
90
91 class Foundation_API ScopedRWLock
92 /// A variant of ScopedLock for reader/writer locks.
93 {
94 public:
95 ScopedRWLock(RWLock& rwl, bool write = false);
96 ~ScopedRWLock();
97
98 private:
99 RWLock& _rwl;
100
101 ScopedRWLock();
102 ScopedRWLock(const ScopedRWLock&);
103 ScopedRWLock& operator = (const ScopedRWLock&);
104 };
105
106
107 class Foundation_API ScopedReadRWLock : public ScopedRWLock
108 /// A variant of ScopedLock for reader locks.
109 {
110 public:
111 ScopedReadRWLock(RWLock& rwl);
112 ~ScopedReadRWLock();
113 };
114
115
116 class Foundation_API ScopedWriteRWLock : public ScopedRWLock
117 /// A variant of ScopedLock for writer locks.
118 {
119 public:
120 ScopedWriteRWLock(RWLock& rwl);
121 ~ScopedWriteRWLock();
122 };
123
124
125 //
126 // inlines
127 //
readLock()128 inline void RWLock::readLock()
129 {
130 readLockImpl();
131 }
132
133
tryReadLock()134 inline bool RWLock::tryReadLock()
135 {
136 return tryReadLockImpl();
137 }
138
139
writeLock()140 inline void RWLock::writeLock()
141 {
142 writeLockImpl();
143 }
144
145
tryWriteLock()146 inline bool RWLock::tryWriteLock()
147 {
148 return tryWriteLockImpl();
149 }
150
151
unlock()152 inline void RWLock::unlock()
153 {
154 unlockImpl();
155 }
156
157
ScopedRWLock(RWLock & rwl,bool write)158 inline ScopedRWLock::ScopedRWLock(RWLock& rwl, bool write): _rwl(rwl)
159 {
160 if (write)
161 _rwl.writeLock();
162 else
163 _rwl.readLock();
164 }
165
166
~ScopedRWLock()167 inline ScopedRWLock::~ScopedRWLock()
168 {
169 try
170 {
171 _rwl.unlock();
172 }
173 catch (...)
174 {
175 poco_unexpected();
176 }
177 }
178
179
ScopedReadRWLock(RWLock & rwl)180 inline ScopedReadRWLock::ScopedReadRWLock(RWLock& rwl): ScopedRWLock(rwl, false)
181 {
182 }
183
184
~ScopedReadRWLock()185 inline ScopedReadRWLock::~ScopedReadRWLock()
186 {
187 }
188
189
ScopedWriteRWLock(RWLock & rwl)190 inline ScopedWriteRWLock::ScopedWriteRWLock(RWLock& rwl): ScopedRWLock(rwl, true)
191 {
192 }
193
194
~ScopedWriteRWLock()195 inline ScopedWriteRWLock::~ScopedWriteRWLock()
196 {
197 }
198
199
200 } // namespace Poco
201
202
203 #endif // Foundation_RWLock_INCLUDED
204