OpenShot Library | OpenShotAudio  0.2.1
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 
27 namespace 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 */
57 template <class LockType>
59 {
60 public:
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 
80 private:
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 */
128 template <class LockType>
130 {
131 public:
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 
155 private:
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 */
200 template <class LockType>
202 {
203 public:
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 
240 private:
241  //==============================================================================
242  const LockType& lock_;
243  mutable bool lockWasSuccessful;
244 
245  JUCE_DECLARE_NON_COPYABLE (GenericScopedTryLock)
246 };
247 
248 } // namespace juce
249 
250 /** @}*/
GenericScopedLock(const LockType &lock) noexcept
Creates a GenericScopedLock.
bool retryLock() const noexcept
Retry gaining the lock by calling tryEnter on the underlying lock.
GenericScopedTryLock(const LockType &lock, bool acquireLockOnInitialisation=true) noexcept
Creates a GenericScopedTryLock.
~GenericScopedLock() noexcept
Destructor.
~GenericScopedTryLock() noexcept
Destructor.
GenericScopedUnlock(const LockType &lock) noexcept
Creates a GenericScopedUnlock.
Automatically locks and unlocks a mutex object.
Automatically locks and unlocks a mutex object.
~GenericScopedUnlock() noexcept
Destructor.
bool isLocked() const noexcept
Returns true if the mutex was successfully locked.
Automatically unlocks and re-locks a mutex object.