2 ==============================================================================
4 This file is part of the JUCE library - "Jules' Utility Class Extensions"
5 Copyright 2004-11 by Raw Material Software Ltd.
7 ------------------------------------------------------------------------------
9 JUCE can be redistributed and/or modified under the terms of the GNU General
10 Public License (Version 2), as published by the Free Software Foundation.
11 A copy of the license is included in the JUCE distribution, or can be found
12 online at www.gnu.org/licenses.
14 JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 A PARTICULAR PURPOSE. See the GNU General Public License for more details.
18 ------------------------------------------------------------------------------
20 To release a closed-source product which uses JUCE, commercial licenses are
21 available: visit www.rawmaterialsoftware.com/juce for more information.
23 ==============================================================================
26 #ifndef __JUCE_CRITICALSECTION_JUCEHEADER__
27 #define __JUCE_CRITICALSECTION_JUCEHEADER__
29 #include "juce_ScopedLock.h"
32 //==============================================================================
36 A CriticalSection acts as a re-entrant mutex lock. The best way to lock and unlock
37 one of these is by using RAII in the form of a local ScopedLock object - have a look
38 through the codebase for many examples of how to do this.
40 @see ScopedLock, ScopedTryLock, ScopedUnlock, SpinLock, ReadWriteLock, Thread, InterProcessLock
42 class JUCE_API CriticalSection
45 //==============================================================================
46 /** Creates a CriticalSection object. */
47 CriticalSection() noexcept
;
50 If the critical section is deleted whilst locked, any subsequent behaviour
53 ~CriticalSection() noexcept
;
55 //==============================================================================
56 /** Acquires the lock.
58 If the lock is already held by the caller thread, the method returns immediately.
59 If the lock is currently held by another thread, this will wait until it becomes free.
61 It's strongly recommended that you never call this method directly - instead use the
62 ScopedLock class to manage the locking using an RAII pattern instead.
64 @see exit, tryEnter, ScopedLock
66 void enter() const noexcept
;
68 /** Attempts to lock this critical section without blocking.
70 This method behaves identically to CriticalSection::enter, except that the caller thread
71 does not wait if the lock is currently held by another thread but returns false immediately.
73 @returns false if the lock is currently held by another thread, true otherwise.
76 bool tryEnter() const noexcept
;
78 /** Releases the lock.
80 If the caller thread hasn't got the lock, this can have unpredictable results.
82 If the enter() method has been called multiple times by the thread, each
83 call must be matched by a call to exit() before other threads will be allowed
84 to take over the lock.
86 @see enter, ScopedLock
88 void exit() const noexcept
;
91 //==============================================================================
92 /** Provides the type of scoped lock to use with a CriticalSection. */
93 typedef GenericScopedLock
<CriticalSection
> ScopedLockType
;
95 /** Provides the type of scoped unlocker to use with a CriticalSection. */
96 typedef GenericScopedUnlock
<CriticalSection
> ScopedUnlockType
;
98 /** Provides the type of scoped try-locker to use with a CriticalSection. */
99 typedef GenericScopedTryLock
<CriticalSection
> ScopedTryLockType
;
103 //==============================================================================
105 // To avoid including windows.h in the public JUCE headers, we'll just allocate a
106 // block of memory here that's big enough to be used internally as a windows critical
107 // section structure.
114 mutable pthread_mutex_t internal
;
117 JUCE_DECLARE_NON_COPYABLE (CriticalSection
);
121 //==============================================================================
123 A class that can be used in place of a real CriticalSection object, but which
124 doesn't perform any locking.
126 This is currently used by some templated classes, and most compilers should
127 manage to optimise it out of existence.
129 @see CriticalSection, Array, OwnedArray, ReferenceCountedArray
131 class JUCE_API DummyCriticalSection
134 inline DummyCriticalSection() noexcept
{}
135 inline ~DummyCriticalSection() noexcept
{}
137 inline void enter() const noexcept
{}
138 inline bool tryEnter() const noexcept
{ return true; }
139 inline void exit() const noexcept
{}
141 //==============================================================================
142 /** A dummy scoped-lock type to use with a dummy critical section. */
143 struct ScopedLockType
145 ScopedLockType (const DummyCriticalSection
&) noexcept
{}
148 /** A dummy scoped-unlocker type to use with a dummy critical section. */
149 typedef ScopedLockType ScopedUnlockType
;
152 JUCE_DECLARE_NON_COPYABLE (DummyCriticalSection
);
155 //==============================================================================
157 Automatically locks and unlocks a CriticalSection object.
159 Use one of these as a local variable to provide RAII-based locking of a CriticalSection.
163 CriticalSection myCriticalSection;
167 const ScopedLock myScopedLock (myCriticalSection);
168 // myCriticalSection is now locked
172 // myCriticalSection gets unlocked here.
176 @see CriticalSection, ScopedUnlock
178 typedef CriticalSection::ScopedLockType ScopedLock
;
180 //==============================================================================
182 Automatically unlocks and re-locks a CriticalSection object.
184 This is the reverse of a ScopedLock object - instead of locking the critical
185 section for the lifetime of this object, it unlocks it.
187 Make sure you don't try to unlock critical sections that aren't actually locked!
191 CriticalSection myCriticalSection;
195 const ScopedLock myScopedLock (myCriticalSection);
196 // myCriticalSection is now locked
198 ... do some stuff with it locked ..
202 ... do some stuff with it locked ..
204 const ScopedUnlock unlocker (myCriticalSection);
206 // myCriticalSection is now unlocked for the remainder of this block,
207 // and re-locked at the end.
209 ...do some stuff with it unlocked ...
212 // myCriticalSection gets unlocked here.
216 @see CriticalSection, ScopedLock
218 typedef CriticalSection::ScopedUnlockType ScopedUnlock
;
220 //==============================================================================
222 Automatically tries to lock and unlock a CriticalSection object.
224 Use one of these as a local variable to control access to a CriticalSection.
227 CriticalSection myCriticalSection;
231 const ScopedTryLock myScopedTryLock (myCriticalSection);
233 // Unlike using a ScopedLock, this may fail to actually get the lock, so you
234 // should test this with the isLocked() method before doing your thread-unsafe
236 if (myScopedTryLock.isLocked())
242 ..our attempt at locking failed because another thread had already locked it..
245 // myCriticalSection gets unlocked here (if it was locked)
249 @see CriticalSection::tryEnter, ScopedLock, ScopedUnlock, ScopedReadLock
251 typedef CriticalSection::ScopedTryLockType ScopedTryLock
;
254 #endif // __JUCE_CRITICALSECTION_JUCEHEADER__