/src/poco/Foundation/include/Poco/RWLock.h
Line | Count | Source (jump to first uncovered line) |
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 | | #include "Poco/RWLock_WIN32.h" |
27 | | #elif POCO_OS == POCO_OS_ANDROID |
28 | | #include "Poco/RWLock_Android.h" |
29 | | #elif defined(POCO_VXWORKS) |
30 | | #include "Poco/RWLock_VX.h" |
31 | | #else |
32 | | #include "Poco/RWLock_POSIX.h" |
33 | | #endif |
34 | | |
35 | | |
36 | | namespace Poco { |
37 | | |
38 | | |
39 | | class ScopedRWLock; |
40 | | class ScopedReadRWLock; |
41 | | class ScopedWriteRWLock; |
42 | | |
43 | | |
44 | | class Foundation_API RWLock: private RWLockImpl |
45 | | /// A reader writer lock allows multiple concurrent |
46 | | /// readers or one exclusive writer. |
47 | | { |
48 | | public: |
49 | | using ScopedLock = ScopedRWLock; |
50 | | using ScopedReadLock = ScopedReadRWLock; |
51 | | using ScopedWriteLock = ScopedWriteRWLock; |
52 | | |
53 | | RWLock(); |
54 | | /// Creates the Reader/Writer lock. |
55 | | |
56 | | ~RWLock(); |
57 | | /// Destroys the Reader/Writer lock. |
58 | | |
59 | | void readLock(); |
60 | | /// Acquires a read lock. If another thread currently holds a write lock, |
61 | | /// waits until the write lock is released. |
62 | | |
63 | | bool tryReadLock(); |
64 | | /// Tries to acquire a read lock. Immediately returns true if successful, or |
65 | | /// false if another thread currently holds a write lock. |
66 | | |
67 | | void writeLock(); |
68 | | /// Acquires a write lock. If one or more other threads currently hold |
69 | | /// locks, waits until all locks are released. The results are undefined |
70 | | /// if the same thread already holds a read or write lock |
71 | | |
72 | | bool tryWriteLock(); |
73 | | /// Tries to acquire a write lock. Immediately returns true if successful, |
74 | | /// or false if one or more other threads currently hold |
75 | | /// locks. The result is undefined if the same thread already |
76 | | /// holds a read or write lock. |
77 | | |
78 | | void unlock(); |
79 | | /// Releases the read or write lock. |
80 | | |
81 | | private: |
82 | | RWLock(const RWLock&); |
83 | | RWLock& operator = (const RWLock&); |
84 | | }; |
85 | | |
86 | | |
87 | | class Foundation_API ScopedRWLock |
88 | | /// A variant of ScopedLock for reader/writer locks. |
89 | | { |
90 | | public: |
91 | | ScopedRWLock(RWLock& rwl, bool write = false); |
92 | | ~ScopedRWLock(); |
93 | | |
94 | | ScopedRWLock() = delete; |
95 | | ScopedRWLock(const ScopedRWLock&) = delete; |
96 | | ScopedRWLock& operator=(const ScopedRWLock&) = delete; |
97 | | |
98 | | private: |
99 | | RWLock& _rwl; |
100 | | }; |
101 | | |
102 | | |
103 | | class Foundation_API ScopedReadRWLock : public ScopedRWLock |
104 | | /// A variant of ScopedLock for reader locks. |
105 | | { |
106 | | public: |
107 | | ScopedReadRWLock(RWLock& rwl); |
108 | | ~ScopedReadRWLock(); |
109 | | }; |
110 | | |
111 | | |
112 | | class Foundation_API ScopedWriteRWLock : public ScopedRWLock |
113 | | /// A variant of ScopedLock for writer locks. |
114 | | { |
115 | | public: |
116 | | ScopedWriteRWLock(RWLock& rwl); |
117 | | ~ScopedWriteRWLock(); |
118 | | }; |
119 | | |
120 | | |
121 | | // |
122 | | // inlines |
123 | | // |
124 | | inline void RWLock::readLock() |
125 | 54.1k | { |
126 | 54.1k | readLockImpl(); |
127 | 54.1k | } |
128 | | |
129 | | |
130 | | inline bool RWLock::tryReadLock() |
131 | 0 | { |
132 | 0 | return tryReadLockImpl(); |
133 | 0 | } |
134 | | |
135 | | |
136 | | inline void RWLock::writeLock() |
137 | 33 | { |
138 | 33 | writeLockImpl(); |
139 | 33 | } |
140 | | |
141 | | |
142 | | inline bool RWLock::tryWriteLock() |
143 | 0 | { |
144 | 0 | return tryWriteLockImpl(); |
145 | 0 | } |
146 | | |
147 | | |
148 | | inline void RWLock::unlock() |
149 | 54.1k | { |
150 | 54.1k | unlockImpl(); |
151 | 54.1k | } |
152 | | |
153 | | |
154 | 54.1k | inline ScopedRWLock::ScopedRWLock(RWLock& rwl, bool write): _rwl(rwl) |
155 | 54.1k | { |
156 | 54.1k | if (write) |
157 | 33 | _rwl.writeLock(); |
158 | 54.1k | else |
159 | 54.1k | _rwl.readLock(); |
160 | 54.1k | } |
161 | | |
162 | | |
163 | | inline ScopedRWLock::~ScopedRWLock() |
164 | 54.1k | { |
165 | 54.1k | try |
166 | 54.1k | { |
167 | 54.1k | _rwl.unlock(); |
168 | 54.1k | } |
169 | 54.1k | catch (...) |
170 | 54.1k | { |
171 | 0 | poco_unexpected(); |
172 | 0 | } |
173 | 54.1k | } |
174 | | |
175 | | |
176 | | inline ScopedReadRWLock::ScopedReadRWLock(RWLock& rwl): ScopedRWLock(rwl, false) |
177 | | { |
178 | | } |
179 | | |
180 | | inline ScopedReadRWLock::~ScopedReadRWLock() = default; |
181 | | |
182 | | inline ScopedWriteRWLock::ScopedWriteRWLock(RWLock& rwl): ScopedRWLock(rwl, true) |
183 | | { |
184 | | } |
185 | | |
186 | | inline ScopedWriteRWLock::~ScopedWriteRWLock() = default; |
187 | | |
188 | | } // namespace Poco |
189 | | |
190 | | |
191 | | #endif // Foundation_RWLock_INCLUDED |