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