#include "../../SDL_internal.h"
extern "C" {
#include "SDL_thread.h"
#include "../SDL_thread_c.h"
#include "../SDL_systhread.h"
}
#include <mutex>
#include <thread>
#include <system_error>
#ifdef __WINRT__
#include <Windows.h>
#endif
static void
RunThread(void *args)
{
SDL_RunThread((SDL_Thread *) args);
}
extern "C"
int
SDL_SYS_CreateThread(SDL_Thread * thread)
{
try {
std::thread cpp_thread(RunThread, thread);
thread->handle = (void *) new std::thread(std::move(cpp_thread));
return 0;
} catch (std::system_error & ex) {
return SDL_SetError("unable to start a C++ thread: code=%d; %s", ex.code(), ex.what());
} catch (std::bad_alloc &) {
return SDL_OutOfMemory();
}
}
extern "C"
void
SDL_SYS_SetupThread(const char *name)
{
SDL_ThreadID();
return;
}
extern "C"
SDL_threadID
SDL_ThreadID(void)
{
#ifdef __WINRT__
return GetCurrentThreadId();
#else
static thread_local SDL_threadID current_thread_id = 0;
static SDL_threadID next_thread_id = 1;
static std::mutex next_thread_id_mutex;
if (current_thread_id == 0) {
std::lock_guard<std::mutex> lock(next_thread_id_mutex);
current_thread_id = next_thread_id;
++next_thread_id;
}
return current_thread_id;
#endif
}
extern "C"
int
SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority)
{
#ifdef __WINRT__
int value;
if (priority == SDL_THREAD_PRIORITY_LOW) {
value = THREAD_PRIORITY_LOWEST;
}
else if (priority == SDL_THREAD_PRIORITY_HIGH) {
value = THREAD_PRIORITY_HIGHEST;
}
else if (priority == SDL_THREAD_PRIORITY_TIME_CRITICAL) {
SDL_LogWarn(SDL_LOG_CATEGORY_SYSTEM, "TIME_CRITICAL unsupported, falling back to HIGHEST");
value = THREAD_PRIORITY_HIGHEST;
}
else {
value = THREAD_PRIORITY_NORMAL;
}
if (!SetThreadPriority(GetCurrentThread(), value)) {
return WIN_SetError("SetThreadPriority()");
}
return 0;
#else
return SDL_Unsupported();
#endif
}
extern "C"
void
SDL_SYS_WaitThread(SDL_Thread * thread)
{
if ( ! thread) {
return;
}
try {
std::thread * cpp_thread = (std::thread *) thread->handle;
if (cpp_thread->joinable()) {
cpp_thread->join();
}
} catch (std::system_error &) {
}
}
extern "C"
void
SDL_SYS_DetachThread(SDL_Thread * thread)
{
if ( ! thread) {
return;
}
try {
std::thread * cpp_thread = (std::thread *) thread->handle;
if (cpp_thread->joinable()) {
cpp_thread->detach();
}
} catch (std::system_error &) {
}
}
extern "C"
SDL_TLSData *
SDL_SYS_GetTLSData(void)
{
return SDL_Generic_GetTLSData();
}
extern "C"
int
SDL_SYS_SetTLSData(SDL_TLSData *data)
{
return SDL_Generic_SetTLSData(data);
}