#include "../../SDL_internal.h"
extern "C" {
#include "SDL_thread.h"
}
#include <chrono>
#include <condition_variable>
#include <ratio>
#include <system_error>
#include "SDL_sysmutex_c.h"
struct SDL_cond
{
std::condition_variable_any cpp_cond;
};
extern "C"
SDL_cond *
SDL_CreateCond(void)
{
try {
SDL_cond * cond = new SDL_cond;
return cond;
} catch (std::system_error & ex) {
SDL_SetError("unable to create a C++ condition variable: code=%d; %s", ex.code(), ex.what());
return NULL;
} catch (std::bad_alloc &) {
SDL_OutOfMemory();
return NULL;
}
}
extern "C"
void
SDL_DestroyCond(SDL_cond * cond)
{
if (cond) {
delete cond;
}
}
extern "C"
int
SDL_CondSignal(SDL_cond * cond)
{
if (!cond) {
return SDL_InvalidParamError("cond");
}
cond->cpp_cond.notify_one();
return 0;
}
extern "C"
int
SDL_CondBroadcast(SDL_cond * cond)
{
if (!cond) {
return SDL_InvalidParamError("cond");
}
cond->cpp_cond.notify_all();
return 0;
}
extern "C"
int
SDL_CondWaitTimeout(SDL_cond * cond, SDL_mutex * mutex, Uint32 ms)
{
if (!cond) {
return SDL_InvalidParamError("cond");
}
if (!mutex) {
return SDL_InvalidParamError("mutex");
}
try {
std::unique_lock<std::recursive_mutex> cpp_lock(mutex->cpp_mutex, std::adopt_lock_t());
if (ms == SDL_MUTEX_MAXWAIT) {
cond->cpp_cond.wait(
cpp_lock
);
cpp_lock.release();
return 0;
} else {
auto wait_result = cond->cpp_cond.wait_for(
cpp_lock,
std::chrono::duration<Uint32, std::milli>(ms)
);
cpp_lock.release();
if (wait_result == std::cv_status::timeout) {
return SDL_MUTEX_TIMEDOUT;
} else {
return 0;
}
}
} catch (std::system_error & ex) {
return SDL_SetError("unable to wait on a C++ condition variable: code=%d; %s", ex.code(), ex.what());
}
}
extern "C"
int
SDL_CondWait(SDL_cond * cond, SDL_mutex * mutex)
{
return SDL_CondWaitTimeout(cond, mutex, SDL_MUTEX_MAXWAIT);
}