diff options
author | chai <chaifix@163.com> | 2019-08-02 20:51:00 +0800 |
---|---|---|
committer | chai <chaifix@163.com> | 2019-08-02 20:51:00 +0800 |
commit | bad78945ceba425f6a80e3b8dca2414d592970eb (patch) | |
tree | 8bf7540766349c534bf9e5746b24fd7507ba034e /source/modules/asura-utils/Threads/Semaphore.cpp | |
parent | 99b90496765df21c5f377f42b9ed073ccb34c1fd (diff) |
*修改文件名格式
Diffstat (limited to 'source/modules/asura-utils/Threads/Semaphore.cpp')
-rw-r--r-- | source/modules/asura-utils/Threads/Semaphore.cpp | 99 |
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 |