98 lines
2.8 KiB
C++
98 lines
2.8 KiB
C++
/***
|
|
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
|
|
|
File: AuSpawnThread.NT.cpp
|
|
Date:
|
|
Author: Reece
|
|
***/
|
|
#include <Source/RuntimeInternal.hpp>
|
|
#include "AuThreads.hpp"
|
|
#include "AuSpawnThread.hpp"
|
|
|
|
#if defined(AURORA_PLATFORM_WIN32)
|
|
#include <process.h>
|
|
#include <Aux_ulib.h>
|
|
#endif
|
|
|
|
namespace Aurora::Threading::Threads
|
|
{
|
|
AuPair<bool, AuUInt> /*success, oshandle*/ SpawnThread(const AuFunction<void()> &entrypoint, const AuString &debugString, AuUInt32 staskSize)
|
|
{
|
|
if (!entrypoint)
|
|
{
|
|
return {false, 0};
|
|
}
|
|
|
|
// i dont like this allocate
|
|
auto callbackClone = _new AuFunction<void()>(entrypoint);
|
|
if (!callbackClone)
|
|
{
|
|
return {false, 0};
|
|
}
|
|
|
|
static auto callVoidPtr_f = [](void *that) -> void
|
|
{
|
|
auto handle = reinterpret_cast<AuFunction<void()> *>(that);
|
|
auto callMe = *handle;
|
|
delete handle;
|
|
callMe();
|
|
};
|
|
|
|
unsigned(WINAPI * OSEP_f)(void *) = [](void *that) -> unsigned
|
|
{
|
|
callVoidPtr_f(that);
|
|
return 0;
|
|
};
|
|
|
|
DWORD(WINAPI * OSCreateThreadEP_f)(void *) = [](void *that) -> DWORD
|
|
{
|
|
callVoidPtr_f(that);
|
|
return 0;
|
|
};
|
|
|
|
#if defined(_DLL) /* dynamic system vcruntime of the 2016+ crt */ || \
|
|
!defined(AURORA_PLATFORM_WIN32)
|
|
|
|
// msvcrt.dll era code should also prefer _beginthreadex
|
|
auto handle = CreateThread(NULL, staskSize, OSCreateThreadEP_f, reinterpret_cast<LPVOID>(callbackClone), NULL, NULL);
|
|
if (!handle)
|
|
{
|
|
handle = INVALID_HANDLE_VALUE;
|
|
SysPushErrorGen("Couldn't create locked thread: {}", debugString);
|
|
return { false, 0 };
|
|
}
|
|
|
|
return { true, reinterpret_cast<AuUInt>(handle) };
|
|
#else
|
|
|
|
#if defined(AURORA_PLATFORM_WIN32)
|
|
BOOL a {};
|
|
if (AuxUlibIsDLLSynchronizationHeld(&a))
|
|
{
|
|
if (a)
|
|
{
|
|
auto handle = CreateThread(NULL, staskSize, OSCreateThreadEP_f, reinterpret_cast<LPVOID>(callbackClone), NULL, NULL);
|
|
if (!handle)
|
|
{
|
|
handle = INVALID_HANDLE_VALUE;
|
|
SysPushErrorGen("Couldn't create locked thread: {}", debugString);
|
|
return {false, 0};
|
|
}
|
|
|
|
return {true, reinterpret_cast<AuUInt>(handle)};
|
|
}
|
|
}
|
|
#endif
|
|
|
|
auto ok = _beginthreadex(nullptr, staskSize, OSEP_f, callbackClone, 0, 0);
|
|
if ((ok == -1L) ||
|
|
(ok == 0))
|
|
{
|
|
SysPushErrorGen("Couldn't initialize thread: {}", debugString);
|
|
return {false, 0};
|
|
}
|
|
|
|
return {true, ok};
|
|
#endif
|
|
}
|
|
} |