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