OpenShot Library | libopenshot-audio 0.2.0
juce_ScopedLock.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 Automatically locks and unlocks a mutex object.
33
34 Use one of these as a local variable to provide RAII-based locking of a mutex.
35
36 The templated class could be a CriticalSection, SpinLock, or anything else that
37 provides enter() and exit() methods.
38
39 e.g. @code
40 CriticalSection myCriticalSection;
41
42 for (;;)
43 {
44 const GenericScopedLock<CriticalSection> myScopedLock (myCriticalSection);
45 // myCriticalSection is now locked
46
47 ...do some stuff...
48
49 // myCriticalSection gets unlocked here.
50 }
51 @endcode
52
53 @see GenericScopedUnlock, CriticalSection, SpinLock, ScopedLock, ScopedUnlock
54
55 @tags{Core}
56*/
57template <class LockType>
59{
60public:
61 //==============================================================================
62 /** Creates a GenericScopedLock.
63
64 As soon as it is created, this will acquire the lock, and when the GenericScopedLock
65 object is deleted, the lock will be released.
66
67 Make sure this object is created and deleted by the same thread,
68 otherwise there are no guarantees what will happen! Best just to use it
69 as a local stack object, rather than creating one with the new() operator.
70 */
71 inline explicit GenericScopedLock (const LockType& lock) noexcept : lock_ (lock) { lock.enter(); }
72
73 /** Destructor.
74 The lock will be released when the destructor is called.
75 Make sure this object is created and deleted by the same thread, otherwise there are
76 no guarantees what will happen!
77 */
78 inline ~GenericScopedLock() noexcept { lock_.exit(); }
79
80private:
81 //==============================================================================
82 const LockType& lock_;
83
84 JUCE_DECLARE_NON_COPYABLE (GenericScopedLock)
85};
86
87
88//==============================================================================
89/**
90 Automatically unlocks and re-locks a mutex object.
91
92 This is the reverse of a GenericScopedLock object - instead of locking the mutex
93 for the lifetime of this object, it unlocks it.
94
95 Make sure you don't try to unlock mutexes that aren't actually locked!
96
97 e.g. @code
98
99 CriticalSection myCriticalSection;
100
101 for (;;)
102 {
103 const GenericScopedLock<CriticalSection> myScopedLock (myCriticalSection);
104 // myCriticalSection is now locked
105
106 ... do some stuff with it locked ..
107
108 while (xyz)
109 {
110 ... do some stuff with it locked ..
111
112 const GenericScopedUnlock<CriticalSection> unlocker (myCriticalSection);
113
114 // myCriticalSection is now unlocked for the remainder of this block,
115 // and re-locked at the end.
116
117 ...do some stuff with it unlocked ...
118 }
119
120 // myCriticalSection gets unlocked here.
121 }
122 @endcode
123
124 @see GenericScopedLock, CriticalSection, ScopedLock, ScopedUnlock
125
126 @tags{Core}
127*/
128template <class LockType>
130{
131public:
132 //==============================================================================
133 /** Creates a GenericScopedUnlock.
134
135 As soon as it is created, this will unlock the CriticalSection, and
136 when the ScopedLock object is deleted, the CriticalSection will
137 be re-locked.
138
139 Make sure this object is created and deleted by the same thread,
140 otherwise there are no guarantees what will happen! Best just to use it
141 as a local stack object, rather than creating one with the new() operator.
142 */
143 inline explicit GenericScopedUnlock (const LockType& lock) noexcept : lock_ (lock) { lock.exit(); }
144
145 /** Destructor.
146
147 The CriticalSection will be unlocked when the destructor is called.
148
149 Make sure this object is created and deleted by the same thread,
150 otherwise there are no guarantees what will happen!
151 */
152 inline ~GenericScopedUnlock() noexcept { lock_.enter(); }
153
154
155private:
156 //==============================================================================
157 const LockType& lock_;
158
159 JUCE_DECLARE_NON_COPYABLE (GenericScopedUnlock)
160};
161
162
163//==============================================================================
164/**
165 Automatically locks and unlocks a mutex object.
166
167 Use one of these as a local variable to provide RAII-based locking of a mutex.
168
169 The templated class could be a CriticalSection, SpinLock, or anything else that
170 provides enter() and exit() methods.
171
172 e.g. @code
173
174 CriticalSection myCriticalSection;
175
176 for (;;)
177 {
178 const GenericScopedTryLock<CriticalSection> myScopedTryLock (myCriticalSection);
179
180 // Unlike using a ScopedLock, this may fail to actually get the lock, so you
181 // should test this with the isLocked() method before doing your thread-unsafe
182 // action..
183 if (myScopedTryLock.isLocked())
184 {
185 ...do some stuff...
186 }
187 else
188 {
189 ..our attempt at locking failed because another thread had already locked it..
190 }
191
192 // myCriticalSection gets unlocked here (if it was locked)
193 }
194 @endcode
195
196 @see CriticalSection::tryEnter, GenericScopedLock, GenericScopedUnlock
197
198 @tags{Core}
199*/
200template <class LockType>
202{
203public:
204 //==============================================================================
205 /** Creates a GenericScopedTryLock.
206
207 If acquireLockOnInitialisation is true then as soon as this ScopedTryLock
208 is created, it will attempt to acquire the lock with tryEnter.
209
210 You can retry acquiring the lock by calling retryLock.
211
212 When GenericScopedTryLock is deleted, the lock will be released (if the lock
213 was successfully acquired).
214
215 Make sure this object is created and deleted by the same thread,
216 otherwise there are no guarantees what will happen! Best just to use it
217 as a local stack object, rather than creating one with the new() operator.
218
219 @see retryLock, isLocked
220 */
221 inline explicit GenericScopedTryLock (const LockType& lock, bool acquireLockOnInitialisation = true) noexcept
222 : lock_ (lock), lockWasSuccessful (acquireLockOnInitialisation && lock.tryEnter()) {}
223
224 /** Destructor.
225
226 The mutex will be unlocked (if it had been successfully locked) when the
227 destructor is called.
228
229 Make sure this object is created and deleted by the same thread,
230 otherwise there are no guarantees what will happen!
231 */
232 inline ~GenericScopedTryLock() noexcept { if (lockWasSuccessful) lock_.exit(); }
233
234 /** Returns true if the mutex was successfully locked. */
235 bool isLocked() const noexcept { return lockWasSuccessful; }
236
237 /** Retry gaining the lock by calling tryEnter on the underlying lock. */
238 bool retryLock() const noexcept { lockWasSuccessful = lock_.tryEnter(); return lockWasSuccessful; }
239
240private:
241 //==============================================================================
242 const LockType& lock_;
243 mutable bool lockWasSuccessful;
244
245 JUCE_DECLARE_NON_COPYABLE (GenericScopedTryLock)
246};
247
248} // namespace juce
249
250/** @}*/
Automatically locks and unlocks a mutex object.
GenericScopedLock(const LockType &lock) noexcept
Creates a GenericScopedLock.
~GenericScopedLock() noexcept
Destructor.
Automatically locks and unlocks a mutex object.
GenericScopedTryLock(const LockType &lock, bool acquireLockOnInitialisation=true) noexcept
Creates a GenericScopedTryLock.
bool isLocked() const noexcept
Returns true if the mutex was successfully locked.
bool retryLock() const noexcept
Retry gaining the lock by calling tryEnter on the underlying lock.
~GenericScopedTryLock() noexcept
Destructor.
Automatically unlocks and re-locks a mutex object.
~GenericScopedUnlock() noexcept
Destructor.
GenericScopedUnlock(const LockType &lock) noexcept
Creates a GenericScopedUnlock.