diff options
author | chai <chaifix@163.com> | 2019-08-14 22:50:43 +0800 |
---|---|---|
committer | chai <chaifix@163.com> | 2019-08-14 22:50:43 +0800 |
commit | 15740faf9fe9fe4be08965098bbf2947e096aeeb (patch) | |
tree | a730ec236656cc8cab5b13f088adfaed6bb218fb /Runtime/Threads/Semaphore.h |
Diffstat (limited to 'Runtime/Threads/Semaphore.h')
-rw-r--r-- | Runtime/Threads/Semaphore.h | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/Runtime/Threads/Semaphore.h b/Runtime/Threads/Semaphore.h new file mode 100644 index 0000000..151f64d --- /dev/null +++ b/Runtime/Threads/Semaphore.h @@ -0,0 +1,67 @@ +#ifndef __SEMAPHORE_H +#define __SEMAPHORE_H + +#if SUPPORT_THREADS + +#if UNITY_WIN || UNITY_XENON +# include "Winapi/PlatformSemaphore.h" +#elif UNITY_LINUX || UNITY_PEPPER || UNITY_ANDROID || UNITY_PS3 || UNITY_BB10 || UNITY_TIZEN +# include "Posix/PlatformSemaphore.h" +#else +# include "PlatformSemaphore.h" +#endif + +#include "Runtime/Utilities/NonCopyable.h" + +class Semaphore : public NonCopyable +{ +public: + Semaphore() { m_Semaphore.Create(); } + ~Semaphore() { m_Semaphore.Destroy(); } + void Reset() { m_Semaphore.Destroy(); m_Semaphore.Create(); } + void WaitForSignal() { m_Semaphore.WaitForSignal(); } + void Signal() { m_Semaphore.Signal(); } + +private: + PlatformSemaphore m_Semaphore; +}; + +class SuspendableSemaphore : public NonCopyable +{ +public: + explicit SuspendableSemaphore(bool suspended = true) : m_Suspended(suspended), m_SuspendedIndefinitely(false) { } + bool IsSuspended() const { return m_Suspended; } + void Reset() { m_Semaphore.Reset(); } + void WaitForSignal() { if (!m_Suspended) m_Semaphore.WaitForSignal(); }; + void Signal() { if (!m_Suspended) m_Semaphore.Signal(); } + void Resume(bool reset = true); + void Suspend(bool indefinitely = false); + +private: + volatile bool m_SuspendedIndefinitely; + volatile bool m_Suspended; + Semaphore m_Semaphore; +}; + +inline void SuspendableSemaphore::Resume(bool reset) +{ + if (reset) + Reset(); + + if (!m_SuspendedIndefinitely) + m_Suspended = false; +} + +inline void SuspendableSemaphore::Suspend(bool indefinitely) +{ + m_Suspended = true; + if (indefinitely) + m_SuspendedIndefinitely = indefinitely; + + m_Semaphore.Signal(); // release any waiting thread +} + + +#endif // SUPPORT_THREADS + +#endif // __SEMAPHORE_H |