[*] Wouldn't it be cool if Linux could safely exit under other conditions without core dumping?
This commit is contained in:
parent
88887434ae
commit
0fe4ad2087
@ -36,8 +36,13 @@
|
||||
void LinuxSuperSecretIOTick();
|
||||
#endif
|
||||
|
||||
|
||||
static thread_local bool tlsHackIsMainThread {};
|
||||
|
||||
static void Init()
|
||||
{
|
||||
gRuntimeRunLevel = 1;
|
||||
tlsHackIsMainThread = true;
|
||||
#if defined(AURORA_PLATFORM_WIN32)
|
||||
Aurora::Extensions::Win32::InitDarkMode();
|
||||
#endif
|
||||
@ -63,6 +68,7 @@ static void Init()
|
||||
Aurora::Processes::Init();
|
||||
Aurora::Hashing::InitHashing();
|
||||
Aurora::Async::InitAsync();
|
||||
gRuntimeRunLevel = 2;
|
||||
}
|
||||
|
||||
static void Pump()
|
||||
@ -76,7 +82,10 @@ static void Pump()
|
||||
|
||||
static void Deinit()
|
||||
{
|
||||
tlsHackIsMainThread = true; // this helps
|
||||
gRuntimeRunLevel = 3;
|
||||
Aurora::Exit::PostLevel(AuThreads::GetThread(), Aurora::Exit::ETriggerLevel::eSafeTermination);
|
||||
gRuntimeRunLevel = 4;
|
||||
Aurora::RNG::Release();
|
||||
Aurora::Async::ShutdownAsync();
|
||||
Aurora::Grug::DeinitGrug();
|
||||
@ -84,12 +93,18 @@ static void Deinit()
|
||||
Aurora::Processes::Deinit();
|
||||
Aurora::Exit::DeinitExit();
|
||||
Aurora::IO::Deinit();
|
||||
gRuntimeRunLevel = 5;
|
||||
}
|
||||
|
||||
namespace Aurora
|
||||
{
|
||||
static bool gRuntimeHasStarted {};
|
||||
|
||||
bool RuntimeIsMainThread()
|
||||
{
|
||||
return tlsHackIsMainThread;
|
||||
}
|
||||
|
||||
AUKN_SYM void RuntimeStart(const RuntimeStartInfo &info)
|
||||
{
|
||||
gRuntimeConfig = info;
|
||||
|
@ -62,5 +62,47 @@
|
||||
#include <AuroraRuntime.hpp>
|
||||
|
||||
inline Aurora::RuntimeStartInfo gRuntimeConfig;
|
||||
inline int gRuntimeRunLevel {0};
|
||||
|
||||
using namespace Aurora::Logging;
|
||||
|
||||
using namespace Aurora::Logging;
|
||||
|
||||
namespace Aurora
|
||||
{
|
||||
#if defined(AU_CFG_ID_DEBUG)
|
||||
static const bool kIsDebugBuild = true;
|
||||
#else
|
||||
static const bool kIsDebugBuild = false;
|
||||
#endif
|
||||
|
||||
bool RuntimeIsMainThread();
|
||||
}
|
||||
|
||||
#define RUNTIME_ASSERT_SHUTDOWN_SAFE(value, ...) \
|
||||
if (gRuntimeRunLevel < 3) \
|
||||
{ \
|
||||
SysAssert(value, __VA_ARGS__); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
if (!bool(value)) \
|
||||
{ \
|
||||
try \
|
||||
{ \
|
||||
AuLogWarn("Error while shutting down: {}", fmt::format(__VA_ARGS__)); \
|
||||
} \
|
||||
catch (...) {} \
|
||||
if (!kIsDebugBuild) SysPushErrorGeneric(__VA_ARGS__); \
|
||||
if (RuntimeIsMainThread()) \
|
||||
{ \
|
||||
if (gRuntimeRunLevel < /*5*/ 4 /*i dont like this and i think i know the problem*/) \
|
||||
{ \
|
||||
SysPanic("Error while shutting down: {}", fmt::format(__VA_ARGS__));\
|
||||
} \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
Threading::Threads::TerminateCurrent(); \
|
||||
} \
|
||||
} \
|
||||
}
|
@ -17,25 +17,25 @@ namespace Aurora::Threading::Primitives
|
||||
{
|
||||
Mutex::Mutex()
|
||||
{
|
||||
auto status = pthread_mutex_init(&value_, nullptr) == 0;
|
||||
auto status = pthread_mutex_init(&this->value_, nullptr) == 0;
|
||||
SysAssert(status, "Mutex init failed");
|
||||
}
|
||||
|
||||
Mutex::~Mutex()
|
||||
{
|
||||
auto status = pthread_mutex_destroy(&value_);
|
||||
SysAssert(status == 0, "Mutex destruct failed, {}", status);
|
||||
int status = pthread_mutex_destroy(&this->value_);
|
||||
RUNTIME_ASSERT_SHUTDOWN_SAFE(status == 0, "Mutex destruct failed, {} {}", status, errno);
|
||||
}
|
||||
|
||||
bool Mutex::HasOSHandle(AuMach &mach)
|
||||
{
|
||||
mach = reinterpret_cast<AuMach>(&value_);
|
||||
mach = reinterpret_cast<AuMach>(&this->value_);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Mutex::TryLock()
|
||||
{
|
||||
return pthread_mutex_trylock(&value_) == 0;
|
||||
return pthread_mutex_trylock(&this->value_) == 0;
|
||||
}
|
||||
|
||||
bool Mutex::HasLockImplementation()
|
||||
@ -56,7 +56,7 @@ namespace Aurora::Threading::Primitives
|
||||
int ret {};
|
||||
do
|
||||
{
|
||||
if ((ret = pthread_mutex_lock(&value_)) == 0)
|
||||
if ((ret = pthread_mutex_lock(&this->value_)) == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -73,7 +73,7 @@ namespace Aurora::Threading::Primitives
|
||||
|
||||
do
|
||||
{
|
||||
ret = pthread_mutex_timedlock(&value_, &tspec);
|
||||
ret = pthread_mutex_timedlock(&this->value_, &tspec);
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
@ -94,7 +94,7 @@ namespace Aurora::Threading::Primitives
|
||||
|
||||
void Mutex::Unlock()
|
||||
{
|
||||
auto status = pthread_mutex_unlock(&value_) == 0;
|
||||
auto status = pthread_mutex_unlock(&this->value_) == 0;
|
||||
SysAssert(status, "Mutex release error");
|
||||
}
|
||||
|
||||
|
@ -11,24 +11,24 @@
|
||||
|
||||
#if !defined(_AURUNTIME_GENERIC_SEMAPHORE) && !defined(AURORA_IS_XNU_DERIVED)
|
||||
#include <Source/Time/Time.hpp>
|
||||
|
||||
|
||||
namespace Aurora::Threading::Primitives
|
||||
{
|
||||
Semaphore::Semaphore(long intialValue)
|
||||
{
|
||||
auto status = sem_init(&value_, 0, intialValue) == 0;
|
||||
auto status = sem_init(&this->value_, 0, intialValue) == 0;
|
||||
SysAssert(status, "Semaphore init failed");
|
||||
}
|
||||
|
||||
Semaphore::~Semaphore()
|
||||
{
|
||||
auto status = sem_destroy(&value_) == 0;
|
||||
SysAssert(status, "Semaphore destroy failed");
|
||||
int status = sem_destroy(&this->value_);
|
||||
RUNTIME_ASSERT_SHUTDOWN_SAFE(status == 0, "Semaphore destroy failed: {} {}", status, errno);
|
||||
}
|
||||
|
||||
bool Semaphore::HasOSHandle(AuMach &mach)
|
||||
{
|
||||
mach = reinterpret_cast<AuMach>(&value_);
|
||||
mach = reinterpret_cast<AuMach>(&this->value_);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -39,7 +39,7 @@ namespace Aurora::Threading::Primitives
|
||||
|
||||
bool Semaphore::TryLock()
|
||||
{
|
||||
return sem_trywait(&value_) == 0;
|
||||
return sem_trywait(&this->value_) == 0;
|
||||
}
|
||||
|
||||
bool Semaphore::Lock(AuUInt64 timeout)
|
||||
@ -50,7 +50,7 @@ namespace Aurora::Threading::Primitives
|
||||
|
||||
do
|
||||
{
|
||||
if ((ret = sem_wait(&value_)) == 0)
|
||||
if ((ret = sem_wait(&this->value_)) == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -69,7 +69,7 @@ namespace Aurora::Threading::Primitives
|
||||
|
||||
do
|
||||
{
|
||||
ret = sem_timedwait(&value_, &tspec);
|
||||
ret = sem_timedwait(&this->value_, &tspec);
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
@ -104,7 +104,7 @@ namespace Aurora::Threading::Primitives
|
||||
|
||||
void Semaphore::Unlock()
|
||||
{
|
||||
auto status = sem_post(&value_) == 0;
|
||||
auto status = sem_post(&this->value_) == 0;
|
||||
SysAssert(status, "Semaphore release error");
|
||||
}
|
||||
|
||||
|
@ -58,11 +58,11 @@ namespace Aurora::Threading::Threads
|
||||
OSThread::OSThread(const ThreadInfo &info) : info_(info)
|
||||
{
|
||||
this->name_ = info.name.value_or("Aurora Thread");
|
||||
this->terminated_ = Primitives::EventShared(true, false);
|
||||
this->terminated_ = Primitives::EventShared(true, false, true);
|
||||
|
||||
// maybe we should atomic exchange compare these when needed frogthink
|
||||
this->terminateSignal_ = Primitives::EventShared(true, false, true);
|
||||
this->terminatedSignalLs_ = AuLoop::NewLSEvent(true, false);
|
||||
this->terminatedSignalLs_ = AuLoop::NewLSEvent(true, false, true);
|
||||
this->terminateSignalLs_ = AuLoop::NewLSEvent(true, false, true);
|
||||
|
||||
this->exitOnlyOnce_ = Primitives::CriticalSectionUnique();
|
||||
@ -114,8 +114,28 @@ namespace Aurora::Threading::Threads
|
||||
}
|
||||
else
|
||||
{
|
||||
Exit();
|
||||
WaitFor(this->terminated_.get());
|
||||
if (gRuntimeRunLevel < 3)
|
||||
{
|
||||
Exit();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Kill the current OS thread instance
|
||||
TeminateOSContext(false);
|
||||
|
||||
// Dispatch kill callback from within an emulated thread context (no switch, just just change thread tls)
|
||||
ExecuteInDeadThread([=]()
|
||||
{
|
||||
this->InternalKill(true);
|
||||
});
|
||||
|
||||
this->exitOnlyOnce_->Unlock();
|
||||
}
|
||||
|
||||
if (gRuntimeRunLevel < 4) // minimum: async deinit level
|
||||
{
|
||||
WaitFor(this->terminated_.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -414,11 +434,24 @@ namespace Aurora::Threading::Threads
|
||||
task_();
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(AURORA_IS_POSIX_DERIVED)
|
||||
catch (...)
|
||||
{
|
||||
SysPushErrorHAL("OS Thread Aborted");
|
||||
}
|
||||
Exit(true);
|
||||
#else
|
||||
catch (...)
|
||||
{
|
||||
if (!Aurora::kIsDebugBuild)
|
||||
{
|
||||
SysPushErrorHAL("OS Thread Aborted");
|
||||
}
|
||||
Exit(true);
|
||||
throw; // bc c-world cant be compatible bc free-iq half-assed software
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void OSThread::ExecuteInDeadThread(AuFunction<void()> callback)
|
||||
|
Loading…
Reference in New Issue
Block a user