diff --git a/src/xrCore/Threading/Event.cpp b/src/xrCore/Threading/Event.cpp index 4cfa4ad22c4..b02e12869e2 100644 --- a/src/xrCore/Threading/Event.cpp +++ b/src/xrCore/Threading/Event.cpp @@ -7,20 +7,75 @@ Event::Event() noexcept { handle = (void*)CreateEvent(NULL, FALSE, FALSE, NULL); Event::~Event() noexcept { CloseHandle(handle); } void Event::Reset() noexcept { ResetEvent(handle); } void Event::Set() noexcept { SetEvent(handle); } -void Event::Wait() const noexcept { WaitForSingleObject(handle, INFINITE); } -bool Event::Wait(u32 millisecondsTimeout) const noexcept +void Event::Wait() noexcept { WaitForSingleObject(handle, INFINITE); } +bool Event::Wait(u32 millisecondsTimeout) noexcept { return WaitForSingleObject(handle, millisecondsTimeout) != WAIT_TIMEOUT; } #elif defined(LINUX) -Event::Event() noexcept { handle = (void*)malloc(1); } -Event::~Event() noexcept { free(handle); } -void Event::Reset() noexcept { memset(handle, 1, 1); } -void Event::Set() noexcept { memset(handle, 0, 1); } -void Event::Wait() const noexcept { Sleep(0); } -bool Event::Wait(u32 millisecondsTimeout) const noexcept +#include +Event::Event() noexcept { - Sleep(millisecondsTimeout); - return true; + m_id.signaled = false; + pthread_mutex_init(&m_id.mutex, nullptr); + pthread_cond_init(&m_id.cond, nullptr); +} +Event::~Event() noexcept +{ + pthread_mutex_destroy(&m_id.mutex); + pthread_cond_destroy(&m_id.cond); +} +void Event::Reset() noexcept +{ + pthread_mutex_lock(&m_id.mutex); + pthread_cond_signal(&m_id.cond); + m_id.signaled = false; + pthread_mutex_unlock(&m_id.mutex); +} +void Event::Set() noexcept +{ + pthread_mutex_lock(&m_id.mutex); + pthread_cond_signal(&m_id.cond); + m_id.signaled = true; + pthread_mutex_unlock(&m_id.mutex); +} +void Event::Wait() noexcept +{ + pthread_mutex_lock(&m_id.mutex); + + while (!m_id.signaled) + { + pthread_cond_wait(&m_id.cond, &m_id.mutex); + } + + pthread_mutex_unlock(&m_id.mutex); +} +bool Event::Wait(u32 millisecondsTimeout) noexcept +{ + bool result = false; + pthread_mutex_lock(&m_id.mutex); + + timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + ts.tv_nsec += (long) millisecondsTimeout * 1000 * 1000; + if(ts.tv_nsec > 1000000000) + { + ts.tv_nsec -= 1000000000; + ts.tv_sec += 1; + } + + while(!m_id.signaled) + { + int res = pthread_cond_timedwait(&m_id.cond, &m_id.mutex, &ts); + if(res == ETIMEDOUT) + { + result = true; + break; + } + } + + pthread_mutex_unlock(&m_id.mutex); + + return result; } #endif diff --git a/src/xrCore/Threading/Event.hpp b/src/xrCore/Threading/Event.hpp index ba42dd19c2c..d97fd898987 100644 --- a/src/xrCore/Threading/Event.hpp +++ b/src/xrCore/Threading/Event.hpp @@ -3,7 +3,20 @@ class XRCORE_API Event { +#if defined(WINDOWS) void* handle; +#elif defined(LINUX) + struct EventHandle + { + pthread_mutex_t mutex; + pthread_cond_t cond; + bool signaled; + }; + pthread_mutex_t handle; + +private: + EventHandle m_id; +#endif public: Event() noexcept;