diff options
author | chai <chaifix@163.com> | 2019-04-02 08:47:15 +0800 |
---|---|---|
committer | chai <chaifix@163.com> | 2019-04-02 08:47:15 +0800 |
commit | 250e30d73f09e9da2b5a81d0fbae63744ae12a73 (patch) | |
tree | 0f55daf334c073e1779d7a1284799a2056aad714 /source/libs/asura-lib-utils/threading/semaphore.cpp | |
parent | 66fe16dd5ed57ae958fc25158d0defae2e6fae6a (diff) |
*misc
Diffstat (limited to 'source/libs/asura-lib-utils/threading/semaphore.cpp')
-rw-r--r-- | source/libs/asura-lib-utils/threading/semaphore.cpp | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/source/libs/asura-lib-utils/threading/semaphore.cpp b/source/libs/asura-lib-utils/threading/semaphore.cpp new file mode 100644 index 0000000..d59ec78 --- /dev/null +++ b/source/libs/asura-lib-utils/threading/semaphore.cpp @@ -0,0 +1,88 @@ +#include "../exceptions/exception.h" +#include "../type.h" + +#include "semaphore.h" + +namespace AsuraEngine +{ + namespace Threading + { + +#define try_create_semaphore(impl) \ + if (!mImpl) \ + { \ + try \ + { \ + mImpl = new impl(init_count); \ + } \ + catch (Exception& e) \ + { \ + mImpl = nullptr; \ + } \ + } + + Semaphore::Semaphore(unsigned int init_count) + : mImpl(nullptr) + { +#ifdef ASURA_THREAD_WIN32 + try_create_semaphore(SemaphoreWin32); +#endif + ASSERT(mImpl); + } + + Semaphore::~Semaphore() + { + if (mImpl) delete mImpl; + } + + void Semaphore::Signal() + { + ASSERT(mImpl); + mImpl->Signal(); + } + + void Semaphore::Wait(int timeout) + { + ASSERT(mImpl); + mImpl->Wait(timeout); + } + +#if ASURA_THREAD_WIN32 + + SemaphoreWin32::SemaphoreWin32(unsigned int init_value) + : SemaphoreImpl(init_value) + { + mSem = CreateSemaphore(NULL, init_value, UINT_MAX, NULL); + if (!mSem) + throw Exception("Cant use win32 semaphore."); + } + + SemaphoreWin32::~SemaphoreWin32() + { + CloseHandle(mSem); + } + + void SemaphoreWin32::Signal() + { + InterlockedIncrement(&mCount); + if (ReleaseSemaphore(mSem, 1, NULL) == FALSE) + InterlockedDecrement(&mCount); + } + + bool SemaphoreWin32::Wait(int timeout) + { + int result; + result = WaitForSingleObject(mSem, timeout < 0 ? INFINITE : timeout); + if (result == WAIT_OBJECT_0) + { + InterlockedDecrement(&mCount); + return true; + } + else + return false; + } + +#endif // ASURA_THREAD_WIN32 + + } +}
\ No newline at end of file |