// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
#pragma once
#if PLATFORM_WIN32
#include "Win32CriticalSection.h"
#include "Engine/Core/Types/BaseTypes.h"
///
/// Win32 implementation of a condition variables. Condition variables are synchronization primitives that enable threads to wait until a particular condition occurs. Condition variables enable threads to atomically release a lock and enter the sleeping state.
///
class FLAXENGINE_API Win32ConditionVariable
{
private:
Windows::CONDITION_VARIABLE _cond;
private:
Win32ConditionVariable(const Win32ConditionVariable&);
Win32ConditionVariable& operator=(const Win32ConditionVariable&);
public:
///
/// Initializes a new instance of the class.
///
Win32ConditionVariable()
{
Windows::InitializeConditionVariable(&_cond);
}
///
/// Finalizes an instance of the class.
///
~Win32ConditionVariable()
{
}
public:
///
/// Blocks the current thread execution until the condition variable is woken up.
///
/// The critical section locked by the current thread.
void Wait(const Win32CriticalSection& lock)
{
Windows::SleepConditionVariableCS(&_cond, &lock._criticalSection, 0xFFFFFFFF);
}
///
/// Blocks the current thread execution until the condition variable is woken up or after the specified timeout duration.
///
/// The critical section locked by the current thread.
/// The time-out interval, in milliseconds. If the time-out interval elapses, the function re-acquires the critical section and returns zero. If timeout is zero, the function tests the states of the specified objects and returns immediately. If timeout is INFINITE, the function's time-out interval never elapses.
/// If the function succeeds, the return value is true, otherwise, if the function fails or the time-out interval elapses, the return value is false.
bool Wait(const Win32CriticalSection& lock, const int32 timeout)
{
return !!Windows::SleepConditionVariableCS(&_cond, &lock._criticalSection, timeout);
}
///
/// Notifies one waiting thread.
///
void NotifyOne()
{
Windows::WakeConditionVariable(&_cond);
}
///
/// Notifies all waiting threads.
///
void NotifyAll()
{
Windows::WakeAllConditionVariable(&_cond);
}
};
#endif