summaryrefslogtreecommitdiff
path: root/source/modules/asura-utils/Threads/Semaphore.cpp
diff options
context:
space:
mode:
authorchai <chaifix@163.com>2019-08-02 20:51:00 +0800
committerchai <chaifix@163.com>2019-08-02 20:51:00 +0800
commitbad78945ceba425f6a80e3b8dca2414d592970eb (patch)
tree8bf7540766349c534bf9e5746b24fd7507ba034e /source/modules/asura-utils/Threads/Semaphore.cpp
parent99b90496765df21c5f377f42b9ed073ccb34c1fd (diff)
*修改文件名格式
Diffstat (limited to 'source/modules/asura-utils/Threads/Semaphore.cpp')
-rw-r--r--source/modules/asura-utils/Threads/Semaphore.cpp99
1 files changed, 99 insertions, 0 deletions
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