1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
|
#if defined(WITH_THREADS)
#include "ThreadSync.h"
#if defined(DEATH_TARGET_WINDOWS)
namespace nCine
{
///////////////////////////////////////////////////////////
// Mutex CLASS
///////////////////////////////////////////////////////////
Mutex::Mutex()
{
::InitializeCriticalSection(&handle_);
}
Mutex::~Mutex()
{
::DeleteCriticalSection(&handle_);
}
void Mutex::Lock()
{
::EnterCriticalSection(&handle_);
}
void Mutex::Unlock()
{
::LeaveCriticalSection(&handle_);
}
int Mutex::TryLock()
{
return ::TryEnterCriticalSection(&handle_);
}
///////////////////////////////////////////////////////////
// CondVariable CLASS
///////////////////////////////////////////////////////////
CondVariable::CondVariable()
: waitersCount_(0)
{
events_[0] = ::CreateEvent(nullptr, FALSE, FALSE, nullptr); // Signal
events_[1] = ::CreateEvent(nullptr, TRUE, FALSE, nullptr); // Broadcast
::InitializeCriticalSection(&waitersCountLock_);
}
CondVariable::~CondVariable()
{
::CloseHandle(events_[0]); // Signal
::CloseHandle(events_[1]); // Broadcast
::DeleteCriticalSection(&waitersCountLock_);
}
void CondVariable::Wait(Mutex& mutex)
{
::EnterCriticalSection(&waitersCountLock_);
waitersCount_++;
::LeaveCriticalSection(&waitersCountLock_);
mutex.Unlock();
WaitEvents();
mutex.Lock();
}
void CondVariable::Signal()
{
::EnterCriticalSection(&waitersCountLock_);
const bool haveWaiters = (waitersCount_ > 0);
::LeaveCriticalSection(&waitersCountLock_);
if (haveWaiters) {
::SetEvent(events_[0]); // Signal
}
}
void CondVariable::Broadcast()
{
::EnterCriticalSection(&waitersCountLock_);
const bool haveWaiters = (waitersCount_ > 0);
::LeaveCriticalSection(&waitersCountLock_);
if (haveWaiters) {
::SetEvent(events_[1]); // Broadcast
}
}
void CondVariable::WaitEvents()
{
const int result = ::WaitForMultipleObjects(2, events_, FALSE, INFINITE);
::EnterCriticalSection(&waitersCountLock_);
waitersCount_--;
const bool isLastWaiter = (result == (WAIT_OBJECT_0 + 1)) && (waitersCount_ == 0);
::LeaveCriticalSection(&waitersCountLock_);
if (isLastWaiter) {
::ResetEvent(events_[1]); // Broadcast
}
}
///////////////////////////////////////////////////////////
// ReadWriteLock CLASS
///////////////////////////////////////////////////////////
ReadWriteLock::ReadWriteLock() : rwlock_(SRWLOCK_INIT)
{
}
ReadWriteLock::~ReadWriteLock()
{
}
}
#endif
#endif
|