/*================================================================================================== CAGuard.h $Log: CAGuard.h,v $ Revision 1.11 2004/08/26 08:13:33 jcm10 finish bring up on Windows Revision 1.10 2003/12/17 21:00:16 dwyatt derive from CAMutex Revision 1.9 2003/12/17 19:49:15 dwyatt Windows conditionalizing Revision 1.8 2003/12/16 18:57:45 dwyatt Windows Revision 1.7 2003/11/22 00:07:10 dwyatt preliminary Win work Revision 1.6 2003/11/20 22:56:53 dwyatt __COREAUDIO_USE_FLAT_INCLUDES__ Revision 1.5 2002/05/07 01:49:45 jcm10 refromat the comment Revision 1.4 2002/04/18 02:20:12 jcm10 clean up the header inclusion Revision 1.3 2002/04/09 07:57:25 bills fix try [jcm10] Revision 1.2 2002/04/02 20:42:07 bills add Try Revision 1.1 2002/03/01 01:52:40 jcm10 moved here from ../Utility Revision 1.7 2001/07/17 20:13:37 jcm10 fix the log line for neatness Revision 1.6 2001/07/04 02:00:26 jcm10 give CAGuard a name for easier debugging Revision 1.5 2001/01/19 00:48:24 jcm10 add more logging Revision 1.4 2001/01/08 23:51:04 jcm10 remove #pragma once, since gcc claims it to be obsolete and issues an annoying warning to that effect when all warnings are enabled Revision 1.3 2000/09/13 02:07:29 jcm10 use CoreAudioTypes.h instead of Revision 1.2 2000/08/25 01:07:26 jcm10 update things to build the XFiles and prune the CoreAudio target to just the code necessary to run it Revision 1.1 2000/08/24 23:36:32 jcm10 first checked in Revision 0.0 2000/01/01 12:34:56 jcm10 created $NoKeywords: $ ==================================================================================================*/ #if !defined(__CAGuard_h__) #define __CAGuard_h__ //================================================================================================== // Includes //============================================================================= // Super Class Includes #include "CAMutex.h" #if CoreAudio_Debug // #define Log_Average_Latency 1 #endif //================================================================================================== // CAGuard // // This is your typical mutex with signalling implemented via pthreads. // Lock() will return true if and only if the guard is locked on that call. // A thread that already has the guard will receive 'false' if it locks it // again. Use of the stack-based CAGuard::Locker class is highly recommended // to properly manage the recursive nesting. The Wait calls with timeouts // will return true if and only if the timeout period expired. They will // return false if they receive notification any other way. //================================================================================================== class CAGuard : public CAMutex { // Construction/Destruction public: CAGuard(const char* inName); virtual ~CAGuard(); // Actions public: virtual void Wait(); virtual bool WaitFor(UInt64 inNanos); virtual bool WaitUntil(UInt64 inNanos); virtual void Notify(); virtual void NotifyAll(); // Implementation protected: #if TARGET_OS_MAC pthread_cond_t mCondVar; #else HANDLE mEvent; #endif #if Log_Average_Latency Float64 mAverageLatencyAccumulator; UInt32 mAverageLatencyCount; #endif // Helper class to manage taking and releasing recursively public: class Locker { // Construction/Destruction public: Locker(CAGuard& inGuard) : mGuard(inGuard), mNeedsRelease(false) { mNeedsRelease = mGuard.Lock(); } ~Locker() { if(mNeedsRelease) { mGuard.Unlock(); } } private: Locker(const Locker&); Locker& operator=(const Locker&); // Actions public: void Wait() { mGuard.Wait(); } bool WaitFor(UInt64 inNanos) { return mGuard.WaitFor(inNanos); } bool WaitUntil(UInt64 inNanos) { return mGuard.WaitUntil(inNanos); } void Notify() { mGuard.Notify(); } void NotifyAll() { mGuard.NotifyAll(); } // Implementation private: CAGuard& mGuard; bool mNeedsRelease; }; }; #endif