From bad78945ceba425f6a80e3b8dca2414d592970eb Mon Sep 17 00:00:00 2001 From: chai Date: Fri, 2 Aug 2019 20:51:00 +0800 Subject: =?UTF-8?q?*=E4=BF=AE=E6=94=B9=E6=96=87=E4=BB=B6=E5=90=8D=E6=A0=BC?= =?UTF-8?q?=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/modules/asura-utils/Threads/Semaphore.cpp | 99 ++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 source/modules/asura-utils/Threads/Semaphore.cpp (limited to 'source/modules/asura-utils/Threads/Semaphore.cpp') diff --git a/source/modules/asura-utils/Threads/Semaphore.cpp b/source/modules/asura-utils/Threads/Semaphore.cpp new file mode 100644 index 0000000..a222f3d --- /dev/null +++ b/source/modules/asura-utils/Threads/Semaphore.cpp @@ -0,0 +1,99 @@ +#include "../Exceptions/Exception.h" +#include "../Type.h" + +#include "Mutex.h" +#include "Semaphore.h" + +namespace_begin(AsuraEngine) +namespace_begin(Threads) + +#define try_create_semaphore(impl) \ +if (!m_Impl) \ +{ \ + try \ + { \ + m_Impl = new impl(init_count); \ + } \ + catch (Exception& e) \ + { \ + m_Impl = nullptr; \ + } \ +} + +Semaphore::Semaphore(unsigned int init_count) + : m_Impl(nullptr) +{ +#ifdef ASURA_THREAD_WIN32 + try_create_semaphore(SemaphoreWin32); +#endif + //ASSERT(m_Impl); +} + +Semaphore::~Semaphore() +{ + if (m_Impl) delete m_Impl; +} + +void Semaphore::Signal() +{ + ASSERT(m_Impl); + m_Impl->Signal(); +} + +bool Semaphore::Wait(int timeout /*= ASURA_MUTEX_MAXWAIT*/) +{ + ASSERT(m_Impl); + return m_Impl->Wait(timeout); +} + +#if ASURA_THREAD_WIN32 + +SemaphoreWin32::SemaphoreWin32(unsigned int init_value) + : SemaphoreImpl(init_value) +{ + // UINT_MAX get error. + m_Sem = CreateSemaphore(NULL, init_value, INT_MAX, NULL); + if (!m_Sem) + { + int errorCode = GetLastError(); + throw Exception("Cant use win32 semaphore. Error code: %d.", errorCode); + } +} + +SemaphoreWin32::~SemaphoreWin32() +{ + CloseHandle(m_Sem); +} + +void SemaphoreWin32::Signal() +{ + InterlockedIncrement(&m_Count); + if (ReleaseSemaphore(m_Sem, 1, NULL) == FALSE) + InterlockedDecrement(&m_Count); +} + +bool SemaphoreWin32::Wait(int timeout) +{ + int result; + result = WaitForSingleObject(m_Sem, timeout); + if (result == WAIT_OBJECT_0) + { + InterlockedDecrement(&m_Count); + return true; + } + else if(result == WAIT_TIMEOUT) + { + // ³¬Ê± + return false; + } + else + { + // δ֪´íÎó + throw Exception("WaitForSingleObject() failed"); + } +} + +#endif // ASURA_THREAD_WIN32 + +namespace_end +namespace_end \ No newline at end of file -- cgit v1.1-26-g67d0