#include "../osbs.inl"
#include "../bthread.h"
#include <sewer/cassert.h>
#if !defined(__WINDOWS__)
#error This file is for Windows system
#endif
#include <sewer/nowarn.hxx>
#include <Windows.h>
#include <sewer/warn.hxx>
Thread *bthread_create_imp(FPtr_thread_main thmain, void *data)
{
HANDLE thread = CreateThread(NULL, 0, cast_func(thmain, LPTHREAD_START_ROUTINE), (LPVOID)data, 0, NULL);
cassert_no_null(thread);
_osbs_thread_alloc();
return cast(thread, Thread);
}
int bthread_current_id(void)
{
return (int)GetCurrentThreadId();
}
void bthread_close(Thread **thread)
{
BOOL ok;
cassert_no_null(thread);
cassert_no_null(*thread);
ok = CloseHandle((HANDLE)*thread);
cassert_unref(ok != 0, ok);
_osbs_thread_dealloc();
*thread = NULL;
}
bool_t bthread_cancel(Thread *thread)
{
cassert_no_null(thread);
return (bool_t)TerminateThread((HANDLE)thread, 0);
}
uint32_t bthread_wait(Thread *thread)
{
DWORD dwWaitResult = 0;
cassert_no_null(thread);
dwWaitResult = WaitForSingleObject((HANDLE)thread, INFINITE);
if (dwWaitResult == WAIT_OBJECT_0)
{
DWORD exit_code = 0;
if (GetExitCodeThread((HANDLE)thread, &exit_code) != 0)
{
return (uint32_t)exit_code;
}
else
{
cassert_msg(FALSE, "Thread join error");
return UINT32_MAX;
}
}
else
{
cassert_msg(FALSE, "Thread join error");
return UINT32_MAX;
}
}
bool_t bthread_finish(Thread *thread, uint32_t *code)
{
DWORD res = 0;
cassert_no_null(thread);
res = WaitForSingleObject((HANDLE)thread, 0);
if (res == WAIT_OBJECT_0)
{
if (code != NULL)
{
DWORD exit_code = 0;
BOOL ok = GetExitCodeThread((HANDLE)thread, &exit_code);
cassert_unref(ok != 0, ok);
*code = (uint32_t)exit_code;
}
return TRUE;
}
else
{
cassert(res == WAIT_TIMEOUT);
return FALSE;
}
}
void bthread_sleep(const uint32_t milliseconds)
{
Sleep(milliseconds);
}