/* ============================================================================== This file is part of the JUCE library - "Jules' Utility Class Extensions" Copyright 2004-11 by Raw Material Software Ltd. ------------------------------------------------------------------------------ JUCE can be redistributed and/or modified under the terms of the GNU General Public License (Version 2), as published by the Free Software Foundation. A copy of the license is included in the JUCE distribution, or can be found online at www.gnu.org/licenses. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. ------------------------------------------------------------------------------ To release a closed-source product which uses JUCE, commercial licenses are available: visit www.rawmaterialsoftware.com/juce for more information. ============================================================================== */ #ifndef __JUCE_SPINLOCK_JUCEHEADER__ #define __JUCE_SPINLOCK_JUCEHEADER__ #include "juce_ScopedLock.h" //============================================================================== /** A simple spin-lock class that can be used as a simple, low-overhead mutex for uncontended situations. Note that unlike a CriticalSection, this type of lock is not re-entrant, and may be less efficient when used it a highly contended situation, but it's very small and requires almost no initialisation. It's most appropriate for simple situations where you're only going to hold the lock for a very brief time. @see CriticalSection */ class JUCE_API SpinLock { public: inline SpinLock() noexcept {} inline ~SpinLock() noexcept {} /** Acquires the lock. This will block until the lock has been successfully acquired by this thread. Note that a SpinLock is NOT re-entrant, and is not smart enough to know whether the caller thread already has the lock - so if a thread tries to acquire a lock that it already holds, this method will never return! It's strongly recommended that you never call this method directly - instead use the ScopedLockType class to manage the locking using an RAII pattern instead. */ void enter() const noexcept; /** Attempts to acquire the lock, returning true if this was successful. */ inline bool tryEnter() const noexcept { return lock.compareAndSetBool (1, 0); } /** Releases the lock. */ inline void exit() const noexcept { jassert (lock.value == 1); // Agh! Releasing a lock that isn't currently held! lock = 0; } //============================================================================== /** Provides the type of scoped lock to use for locking a SpinLock. */ typedef GenericScopedLock ScopedLockType; /** Provides the type of scoped unlocker to use with a SpinLock. */ typedef GenericScopedUnlock ScopedUnlockType; private: //============================================================================== mutable Atomic lock; JUCE_DECLARE_NON_COPYABLE (SpinLock); }; #endif // __JUCE_SPINLOCK_JUCEHEADER__