OpenShot Library | OpenShotAudio  0.2.1
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 
27 namespace 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 {
48 public:
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 
106 private:
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 {
139 public:
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 
157 private:
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 /** @}*/
#define JUCE_API
This macro is added to all JUCE public class declarations.
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&#39;t perform any loc...
A dummy scoped-lock type to use with a dummy critical section.
A re-entrant mutex.
Automatically locks and unlocks a mutex object.
GenericScopedLock< CriticalSection > ScopedLockType
Provides the type of scoped lock to use with a CriticalSection.
Automatically locks and unlocks a mutex object.
Automatically unlocks and re-locks a mutex object.
GenericScopedUnlock< CriticalSection > ScopedUnlockType
Provides the type of scoped unlocker to use with a CriticalSection.