OpenShot Library | libopenshot-audio 0.2.0
juce_CriticalSection.h
1
2/** @weakgroup juce_core-threads
3 * @{
4 */
5/*
6 ==============================================================================
7
8 This file is part of the JUCE library.
9 Copyright (c) 2017 - ROLI Ltd.
10
11 JUCE is an open source library subject to commercial or open-source
12 licensing.
13
14 The code included in this file is provided under the terms of the ISC license
15 http://www.isc.org/downloads/software-support-policy/isc-license. Permission
16 To use, copy, modify, and/or distribute this software for any purpose with or
17 without fee is hereby granted provided that the above copyright notice and
18 this permission notice appear in all copies.
19
20 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
21 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
22 DISCLAIMED.
23
24 ==============================================================================
25*/
26
27namespace juce
28{
29
30//==============================================================================
31/**
32 A re-entrant mutex.
33
34 A CriticalSection acts as a re-entrant mutex object. The best way to lock and unlock
35 one of these is by using RAII in the form of a local ScopedLock object - have a look
36 through the codebase for many examples of how to do this.
37
38 In almost all cases you'll want to declare your CriticalSection as a member variable.
39 Occasionally you may want to declare one as a static variable, but in that case the usual
40 C++ static object order-of-construction warnings should be heeded.
41
42 @see ScopedLock, ScopedTryLock, ScopedUnlock, SpinLock, ReadWriteLock, Thread, InterProcessLock
43
44 @tags{Core}
45*/
47{
48public:
49 //==============================================================================
50 /** Creates a CriticalSection object. */
51 CriticalSection() noexcept;
52
53 /** Destructor.
54 If the critical section is deleted whilst locked, any subsequent behaviour
55 is unpredictable.
56 */
57 ~CriticalSection() noexcept;
58
59 //==============================================================================
60 /** Acquires the lock.
61
62 If the lock is already held by the caller thread, the method returns immediately.
63 If the lock is currently held by another thread, this will wait until it becomes free.
64
65 It's strongly recommended that you never call this method directly - instead use the
66 ScopedLock class to manage the locking using an RAII pattern instead.
67
68 @see exit, tryEnter, ScopedLock
69 */
70 void enter() const noexcept;
71
72 /** Attempts to lock this critical section without blocking.
73
74 This method behaves identically to CriticalSection::enter, except that the caller thread
75 does not wait if the lock is currently held by another thread but returns false immediately.
76
77 @returns false if the lock is currently held by another thread, true otherwise.
78 @see enter
79 */
80 bool tryEnter() const noexcept;
81
82 /** Releases the lock.
83
84 If the caller thread hasn't got the lock, this can have unpredictable results.
85
86 If the enter() method has been called multiple times by the thread, each
87 call must be matched by a call to exit() before other threads will be allowed
88 to take over the lock.
89
90 @see enter, ScopedLock
91 */
92 void exit() const noexcept;
93
94
95 //==============================================================================
96 /** Provides the type of scoped lock to use with a CriticalSection. */
98
99 /** Provides the type of scoped unlocker to use with a CriticalSection. */
101
102 /** Provides the type of scoped try-locker to use with a CriticalSection. */
104
105
106private:
107 //==============================================================================
108 #if JUCE_WINDOWS
109 // To avoid including windows.h in the public JUCE headers, we'll just allocate
110 // a block of memory here that's big enough to be used internally as a windows
111 // CRITICAL_SECTION structure.
112 #if JUCE_64BIT
113 uint8 lock[44];
114 #else
115 uint8 lock[24];
116 #endif
117 #else
118 mutable pthread_mutex_t lock;
119 #endif
120
121 JUCE_DECLARE_NON_COPYABLE (CriticalSection)
122};
123
124
125//==============================================================================
126/**
127 A class that can be used in place of a real CriticalSection object, but which
128 doesn't perform any locking.
129
130 This is currently used by some templated classes, and most compilers should
131 manage to optimise it out of existence.
132
133 @see CriticalSection, Array, OwnedArray, ReferenceCountedArray
134
135 @tags{Core}
136*/
138{
139public:
140 inline DummyCriticalSection() = default;
141 inline ~DummyCriticalSection() = default;
142
143 inline void enter() const noexcept {}
144 inline bool tryEnter() const noexcept { return true; }
145 inline void exit() const noexcept {}
146
147 //==============================================================================
148 /** A dummy scoped-lock type to use with a dummy critical section. */
150 {
151 ScopedLockType (const DummyCriticalSection&) noexcept {}
152 };
153
154 /** A dummy scoped-unlocker type to use with a dummy critical section. */
156
157private:
158 JUCE_DECLARE_NON_COPYABLE (DummyCriticalSection)
159};
160
161//==============================================================================
162/**
163 Automatically locks and unlocks a CriticalSection object.
164
165 You can use a ScopedLock as a local variable to provide RAII-based locking of a CriticalSection.
166
167 e.g. @code
168
169 struct MyObject
170 {
171 CriticalSection objectLock;
172
173 // assuming that this example function will be called by multiple threads
174 void foo()
175 {
176 const ScopedLock myScopedLock (objectLock);
177
178 // objectLock is now locked..
179
180 ...do some thread-safe work here...
181
182 // ..and objectLock gets unlocked here, as myScopedLock goes out of
183 // scope at the end of the block
184 }
185 };
186 @endcode
187
188 @see CriticalSection, ScopedUnlock
189*/
191
192//==============================================================================
193/**
194 Automatically unlocks and re-locks a CriticalSection object.
195
196 This is the reverse of a ScopedLock object - instead of locking the critical
197 section for the lifetime of this object, it unlocks it.
198
199 Make sure you don't try to unlock critical sections that aren't actually locked!
200
201 e.g. @code
202
203 struct MyObject
204 {
205 CriticalSection objectLock;
206
207 void foo()
208 {
209 {
210 const ScopedLock myScopedLock (objectLock);
211
212 // objectLock is now locked..
213
214 {
215 ScopedUnlock myUnlocker (objectLock);
216
217 // ..and now unlocked..
218 }
219
220 // ..and now locked again..
221 }
222
223 // ..and finally unlocked.
224 }
225 };
226 @endcode
227
228 @see CriticalSection, ScopedLock
229*/
231
232//==============================================================================
233/**
234 Automatically tries to lock and unlock a CriticalSection object.
235
236 Use one of these as a local variable to control access to a CriticalSection.
237
238 e.g. @code
239
240 struct MyObject
241 {
242 CriticalSection objectLock;
243
244 void foo()
245 {
246 const ScopedTryLock myScopedTryLock (objectLock);
247
248 // Unlike using a ScopedLock, this may fail to actually get the lock, so you
249 // must call the isLocked() method before making any assumptions..
250 if (myScopedTryLock.isLocked())
251 {
252 ...safely do some work...
253 }
254 else
255 {
256 // If we get here, then our attempt at locking failed because another thread had already locked it..
257 }
258 }
259 };
260 @endcode
261
262 @see CriticalSection::tryEnter, ScopedLock, ScopedUnlock, ScopedReadLock
263*/
265
266} // namespace juce
267
268/** @}*/
GenericScopedLock< CriticalSection > ScopedLockType
Provides the type of scoped lock to use with a CriticalSection.
GenericScopedUnlock< CriticalSection > ScopedUnlockType
Provides the type of scoped unlocker to use with a CriticalSection.
CriticalSection() noexcept
Creates a CriticalSection object.
GenericScopedTryLock< CriticalSection > ScopedTryLockType
Provides the type of scoped try-locker to use with a CriticalSection.
A class that can be used in place of a real CriticalSection object, but which doesn't perform any loc...
Automatically locks and unlocks a mutex object.
Automatically locks and unlocks a mutex object.
Automatically unlocks and re-locks a mutex object.
#define JUCE_API
This macro is added to all JUCE public class declarations.
A dummy scoped-lock type to use with a dummy critical section.