1//
2// Mutex.h
3//
4// Library: Foundation
5// Package: Threading
6// Module: Mutex
7//
8// Definition of the Mutex and FastMutex classes.
9//
10// Copyright (c) 2004-2008, Applied Informatics Software Engineering GmbH.
11// and Contributors.
12//
13// SPDX-License-Identifier: BSL-1.0
14//
15
16
17#ifndef Foundation_Mutex_INCLUDED
18#define Foundation_Mutex_INCLUDED
19
20
21#include "Poco/Foundation.h"
22#include "Poco/Exception.h"
23#include "Poco/ScopedLock.h"
24
25#if (POCO_OS == POCO_OS_CYGWIN || defined(POCO_ANDROID))
26#include "Poco/Mutex_POSIX.h"
27#else
28#include "Poco/Mutex_STD.h"
29#endif
30
31namespace Poco {
32
33
34class Foundation_API Mutex: private MutexImpl
35 /// A Mutex (mutual exclusion) is a synchronization
36 /// mechanism used to control access to a shared resource
37 /// in a concurrent (multithreaded) scenario.
38 /// Using the ScopedLock class is the preferred way to automatically
39 /// lock and unlock a mutex.
40{
41public:
42 enum MutexType
43 /// The type of a mutex.
44 {
45 MUTEX_RECURSIVE = MUTEX_RECURSIVE_IMPL, /// A recursive mutex
46 MUTEX_NONRECURSIVE = MUTEX_NONRECURSIVE_IMPL /// A non-recursive mutex
47 };
48
49 typedef Poco::ScopedLock<Mutex> ScopedLock;
50
51 explicit Mutex(MutexType type = MUTEX_RECURSIVE);
52 /// Creates the Mutex.
53
54 ~Mutex();
55 /// Destroys the Mutex.
56
57 void lock();
58 /// Locks the mutex. Blocks if the mutex
59 /// is held by another thread.
60
61 void lock(long milliseconds);
62 /// Locks the mutex. Blocks up to the given number of milliseconds
63 /// if the mutex is held by another thread. Throws a TimeoutException
64 /// if the mutex can not be locked within the given timeout.
65 ///
66 /// Performance Note: On most platforms (including Windows), this member function is
67 /// implemented using a loop calling (the equivalent of) tryLock() and Thread::sleep().
68 /// On POSIX platforms that support pthread_mutex_timedlock(), this is used.
69
70 bool tryLock();
71 /// Tries to lock the mutex. Returns false immediately
72 /// if the mutex is already held by another thread.
73 /// Returns true if the mutex was successfully locked.
74
75 bool tryLock(long milliseconds);
76 /// Locks the mutex. Blocks up to the given number of milliseconds
77 /// if the mutex is held by another thread.
78 /// Returns true if the mutex was successfully locked.
79 ///
80 /// Performance Note: On most platforms (including Windows), this member function is
81 /// implemented using a loop calling (the equivalent of) tryLock() and Thread::sleep().
82 /// On POSIX platforms that support pthread_mutex_timedlock(), this is used.
83
84 void unlock();
85 /// Unlocks the mutex so that it can be acquired by
86 /// other threads.
87
88private:
89 Mutex(const Mutex&);
90 Mutex& operator = (const Mutex&);
91};
92
93
94class Foundation_API FastMutex: private FastMutexImpl
95 /// A FastMutex (mutual exclusion) is similar to a Mutex.
96 /// Locking a FastMutex is guaranteed to be at least as
97 /// fast as locking a Mutex. However, a FastMutex is not
98 /// guaranteed to be either recursive or non-recursive.
99 /// It is best suited to thread safe components like pools,
100 /// caches and queues where locking is internal to the component.
101 /// Using the ScopedLock class is the preferred way to automatically
102 /// lock and unlock a mutex.
103{
104public:
105 typedef Poco::ScopedLock<FastMutex> ScopedLock;
106
107 FastMutex();
108 /// creates the Mutex.
109
110 ~FastMutex();
111 /// destroys the Mutex.
112
113 void lock();
114 /// Locks the mutex. Blocks if the mutex
115 /// is held by another thread.
116
117 void lock(long milliseconds);
118 /// Locks the mutex. Blocks up to the given number of milliseconds
119 /// if the mutex is held by another thread. Throws a TimeoutException
120 /// if the mutex can not be locked within the given timeout.
121 ///
122 /// Performance Note: On most platforms (including Windows), this member function is
123 /// implemented using a loop calling (the equivalent of) tryLock() and Thread::sleep().
124 /// On POSIX platforms that support pthread_mutex_timedlock(), this is used.
125
126 bool tryLock();
127 /// Tries to lock the mutex. Returns false immediately
128 /// if the mutex is already held by another thread.
129 /// Returns true if the mutex was successfully locked.
130
131 bool tryLock(long milliseconds);
132 /// Locks the mutex. Blocks up to the given number of milliseconds
133 /// if the mutex is held by another thread.
134 /// Returns true if the mutex was successfully locked.
135 ///
136 /// Performance Note: On most platforms (including Windows), this member function is
137 /// implemented using a loop calling (the equivalent of) tryLock() and Thread::sleep().
138 /// On POSIX platforms that support pthread_mutex_timedlock(), this is used.
139
140 void unlock();
141 /// Unlocks the mutex so that it can be acquired by
142 /// other threads.
143
144private:
145 FastMutex(const FastMutex&);
146 FastMutex& operator = (const FastMutex&);
147};
148
149
150class Foundation_API NullMutex
151 /// A NullMutex is an empty mutex implementation
152 /// which performs no locking at all. Useful in policy driven design
153 /// where the type of mutex used can be now a template parameter allowing the user to switch
154 /// between thread-safe and not thread-safe depending on his need
155 /// Works with the ScopedLock class
156{
157public:
158 typedef Poco::ScopedLock<NullMutex> ScopedLock;
159
160 NullMutex()
161 /// Creates the NullMutex.
162 {
163 }
164
165 ~NullMutex()
166 /// Destroys the NullMutex.
167 {
168 }
169
170 void lock()
171 /// Does nothing.
172 {
173 }
174
175 void lock(long)
176 /// Does nothing.
177 {
178 }
179
180 bool tryLock()
181 /// Does nothing and always returns true.
182 {
183 return true;
184 }
185
186 bool tryLock(long)
187 /// Does nothing and always returns true.
188 {
189 return true;
190 }
191
192 void unlock()
193 /// Does nothing.
194 {
195 }
196};
197
198
199//
200// inlines
201//
202inline void Mutex::lock()
203{
204 lockImpl();
205}
206
207
208inline void Mutex::lock(long milliseconds)
209{
210 if (!tryLockImpl(milliseconds))
211 throw TimeoutException();
212}
213
214
215inline bool Mutex::tryLock()
216{
217 return tryLockImpl();
218}
219
220
221inline bool Mutex::tryLock(long milliseconds)
222{
223 return tryLockImpl(milliseconds);
224}
225
226
227inline void Mutex::unlock()
228{
229 unlockImpl();
230}
231
232
233inline void FastMutex::lock()
234{
235 lockImpl();
236}
237
238
239inline void FastMutex::lock(long milliseconds)
240{
241 if (!tryLockImpl(milliseconds))
242 throw TimeoutException();
243}
244
245
246inline bool FastMutex::tryLock()
247{
248 return tryLockImpl();
249}
250
251
252inline bool FastMutex::tryLock(long milliseconds)
253{
254 return tryLockImpl(milliseconds);
255}
256
257
258inline void FastMutex::unlock()
259{
260 unlockImpl();
261}
262
263
264} // namespace Poco
265
266
267#endif // Foundation_Mutex_INCLUDED
268