2012-06-14 09:06:06 -04:00
|
|
|
|
2012-09-23 17:23:33 -04:00
|
|
|
// Event.cpp
|
2012-06-14 09:06:06 -04:00
|
|
|
|
|
|
|
// Implements the cEvent object representing an OS-specific synchronization primitive that can be waited-for
|
|
|
|
// Implemented as an Event on Win and as a 1-semaphore on *nix
|
|
|
|
|
|
|
|
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
|
|
|
|
|
2012-09-23 17:23:33 -04:00
|
|
|
#include "Event.h"
|
2014-01-25 09:02:20 -05:00
|
|
|
#include "Errors.h"
|
2012-06-14 09:06:06 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-10-23 05:20:25 -04:00
|
|
|
cEvent::cEvent(void) :
|
|
|
|
m_ShouldWait(true)
|
2012-06-14 09:06:06 -04:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-10-23 05:20:25 -04:00
|
|
|
void cEvent::Wait(void)
|
2012-06-14 09:06:06 -04:00
|
|
|
{
|
2014-10-23 05:20:25 -04:00
|
|
|
std::unique_lock<std::mutex> Lock(m_Mutex);
|
|
|
|
while (m_ShouldWait)
|
2012-06-14 09:06:06 -04:00
|
|
|
{
|
2014-10-23 05:20:25 -04:00
|
|
|
m_CondVar.wait(Lock);
|
2012-06-14 09:06:06 -04:00
|
|
|
}
|
2014-10-23 05:20:25 -04:00
|
|
|
m_ShouldWait = true;
|
2012-06-14 09:06:06 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-12-07 15:37:47 -05:00
|
|
|
bool cEvent::Wait(unsigned a_TimeoutMSec)
|
2014-10-05 13:04:30 -04:00
|
|
|
{
|
2014-12-07 15:37:47 -05:00
|
|
|
auto dst = std::chrono::system_clock::now() + std::chrono::milliseconds(a_TimeoutMSec);
|
2014-10-23 05:20:25 -04:00
|
|
|
std::unique_lock<std::mutex> Lock(m_Mutex); // We assume that this lock is acquired without much delay - we are the only user of the mutex
|
2014-12-07 15:37:47 -05:00
|
|
|
while (m_ShouldWait && (std::chrono::system_clock::now() <= dst))
|
2014-10-23 05:20:25 -04:00
|
|
|
{
|
|
|
|
switch (m_CondVar.wait_until(Lock, dst))
|
2014-10-05 13:04:30 -04:00
|
|
|
{
|
2014-10-23 05:20:25 -04:00
|
|
|
case std::cv_status::no_timeout:
|
2014-10-05 13:04:30 -04:00
|
|
|
{
|
2014-10-23 05:20:25 -04:00
|
|
|
// The wait was successful, check for spurious wakeup:
|
|
|
|
if (!m_ShouldWait)
|
|
|
|
{
|
|
|
|
m_ShouldWait = true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
// This was a spurious wakeup, wait again:
|
|
|
|
continue;
|
2014-10-05 13:04:30 -04:00
|
|
|
}
|
2014-10-23 05:20:25 -04:00
|
|
|
|
|
|
|
case std::cv_status::timeout:
|
2014-10-05 13:04:30 -04:00
|
|
|
{
|
2014-10-23 05:20:25 -04:00
|
|
|
// The wait timed out, return failure:
|
2014-10-05 13:04:30 -04:00
|
|
|
return false;
|
|
|
|
}
|
2014-10-23 05:20:25 -04:00
|
|
|
} // switch (wait_until())
|
|
|
|
} // while (m_ShouldWait && not timeout)
|
|
|
|
|
2014-12-11 08:34:09 -05:00
|
|
|
// The wait timed out in the while condition:
|
2014-10-23 05:20:25 -04:00
|
|
|
return false;
|
2014-10-05 13:04:30 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2012-06-14 09:06:06 -04:00
|
|
|
void cEvent::Set(void)
|
|
|
|
{
|
2014-10-23 05:20:25 -04:00
|
|
|
{
|
|
|
|
std::unique_lock<std::mutex> Lock(m_Mutex);
|
|
|
|
m_ShouldWait = false;
|
|
|
|
}
|
|
|
|
m_CondVar.notify_one();
|
2013-08-14 16:27:49 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|