summaryrefslogtreecommitdiff
path: root/source/libs/asura-lib-utils/threading/semaphore.cpp
diff options
context:
space:
mode:
authorchai <chaifix@163.com>2019-04-02 08:47:15 +0800
committerchai <chaifix@163.com>2019-04-02 08:47:15 +0800
commit250e30d73f09e9da2b5a81d0fbae63744ae12a73 (patch)
tree0f55daf334c073e1779d7a1284799a2056aad714 /source/libs/asura-lib-utils/threading/semaphore.cpp
parent66fe16dd5ed57ae958fc25158d0defae2e6fae6a (diff)
*misc
Diffstat (limited to 'source/libs/asura-lib-utils/threading/semaphore.cpp')
-rw-r--r--source/libs/asura-lib-utils/threading/semaphore.cpp88
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