AuroraRuntime/Source/Threading/Threads/SpawnThread.NT.cpp
Reece e5e36bd887 Large Commit
[*] Fix deadlock in the async subsystem (NoLockShutdown vs Shutdown in exception handler)
[+] Added ProccessMap NT variant
[+] Added ToolHelp image profiling
[*] Improved exception awareness
[*] Delegated SpawnThread to isolated TU, ready for reuse for RunAs and XNU Open - now with horrible evil alloc that could fail
[+] Added header for future api 'UtilRun'
[*] Improve NT core detection
[*] Changed small affinity bitmap to AuUInt64 instead of AuUInt32
[+] Added data structure to hold cpuids/affinity masks
[+] Implemented logger sinks
[+] Implemented logger glue logic
[*] Began migrating older loggers to sink-based default devices
[*] Minor refactors
[*] Improved internal exception discarding, not yet nothrow capable
[*] Minor create directory fix
2022-01-24 18:43:53 +00:00

93 lines
3.1 KiB
C++

/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: SpawnThread.NT.cpp
Date:
Author: Reece
***/
#include <Source/RuntimeInternal.hpp>
#include "Threads.hpp"
#include "SpawnThread.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)
{
// https://github.com/webrtc-uwp/chromium-base/blob/master/threading/platform_thread_win.cc#L129-L136
// Do we care yet?
// When targeting older CRTs, _beginthreadex
// When targeting at least UWP, CreateThread but _beginthreadex is fine
// https://web.archive.org/web/20110928122401/http://www.microsoft.com/msj/1099/win32/win321099.aspx
// Even in 1999 it sounded like _tiddata was setup for all modules that may come across our thread
// It wasn't until 2005, 6 years later, it became less of a requirement.
// Does the modern CRT need it for anything estoeric or evil?
// I think so long as we're targeting modern windows its fine to call _beginthreadex for all CRT users
// Userland icds, plugins, software not in our build chain, it makes sense for them to have a _fully_ initialized crt
// I think I switched it from CreateThread to _beginthreadex at somepoint and i don't remember why
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(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)
{
SysPushErrorGen("Couldn't initialize thread: {}", debugString);
return {false, 0};
}
return {true, ok};
}
}