[*] Various teardown related fixes/changes under UNIX

This commit is contained in:
Reece Wilson 2022-08-14 14:41:19 +01:00
parent 0fe4ad2087
commit 7fd217a50e
5 changed files with 105 additions and 23 deletions

View File

@ -38,6 +38,7 @@ namespace Aurora::Console::ConsoleTTY
void TTYConsole::Deinit() void TTYConsole::Deinit()
{ {
this->End();
this->HistoryAppendChanges(); this->HistoryAppendChanges();
} }
@ -76,7 +77,15 @@ namespace Aurora::Console::ConsoleTTY
void TTYConsole::End() void TTYConsole::End()
{ {
gTTYConsoleEnabled = false; if (!AuExchange(gTTYConsoleEnabled, false))
{
return;
}
if (NoncanonicalMode())
{
ConsoleStd::LeaveNoncanonicalMode();
}
TTYClearScreen(); TTYClearScreen();
TTYClearLine(EAnsiColor::eReset); TTYClearLine(EAnsiColor::eReset);
@ -85,11 +94,6 @@ namespace Aurora::Console::ConsoleTTY
TTYWrite("\033[?1049l"); TTYWrite("\033[?1049l");
#endif #endif
if (NoncanonicalMode())
{
ConsoleStd::LeaveNoncanonicalMode();
}
#if defined(AURORA_IS_MODERNNT_DERIVED) #if defined(AURORA_IS_MODERNNT_DERIVED)
SetConsoleOutputCP(this->oldCP); SetConsoleOutputCP(this->oldCP);
#endif #endif
@ -98,6 +102,11 @@ namespace Aurora::Console::ConsoleTTY
{ {
TTYWrite("\033(B"); TTYWrite("\033(B");
} }
#if defined(AURORA_IS_POSIX_DERIVED)
ConsoleStd::Unlock(); // just really making sure
#endif
ConsoleStd::Flush();
} }
void TTYConsole::BufferMessage(const AuConsole::ConsoleMessage &msg) void TTYConsole::BufferMessage(const AuConsole::ConsoleMessage &msg)

View File

@ -80,15 +80,22 @@ static void Pump()
#endif #endif
} }
static void RuntimeLateClean();
static void Deinit() static void Deinit()
{ {
tlsHackIsMainThread = true; // this helps tlsHackIsMainThread = true;
gRuntimeRunLevel = 3; gRuntimeRunLevel = 3;
Aurora::Exit::PostLevel(AuThreads::GetThread(), Aurora::Exit::ETriggerLevel::eSafeTermination); Aurora::Exit::PostLevel(AuThreads::GetThread(), Aurora::Exit::ETriggerLevel::eSafeTermination);
gRuntimeRunLevel = 4; gRuntimeRunLevel = 4;
Aurora::RNG::Release(); Aurora::RNG::Release();
Aurora::Async::ShutdownAsync(); Aurora::Async::ShutdownAsync();
Aurora::Grug::DeinitGrug(); Aurora::Grug::DeinitGrug();
RuntimeLateClean();
}
static void RuntimeLateClean() // strictly IO flushing + DeinitGrug can sometimes fail under POSIX
{
Aurora::Console::Exit(); Aurora::Console::Exit();
Aurora::Processes::Deinit(); Aurora::Processes::Deinit();
Aurora::Exit::DeinitExit(); Aurora::Exit::DeinitExit();
@ -140,6 +147,11 @@ namespace Aurora
{ {
Pump(); Pump();
} }
void RuntimeLateClean()
{
::RuntimeLateClean();
}
} }
#if defined(AURORA_PLATFORM_WIN32) #if defined(AURORA_PLATFORM_WIN32)

View File

@ -13,6 +13,7 @@
#include <dlfcn.h> #include <dlfcn.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <signal.h>
#endif #endif
#if defined(AURORA_PLATFORM_WIN32) #if defined(AURORA_PLATFORM_WIN32)
@ -548,7 +549,12 @@ namespace Aurora::Process
#if defined(AURORA_IS_MODERNNT_DERIVED) #if defined(AURORA_IS_MODERNNT_DERIVED)
ExitProcess(exitcode); ExitProcess(exitcode);
#elif defined(AURORA_IS_POSIX_DERIVED) #elif defined(AURORA_IS_POSIX_DERIVED)
exit(exitcode); // TODO: if main thread, long jump back, and return exit code
::kill(getpgrp(), SIGKILL);
while (true)
{
::sched_yield();
}
#else #else
// ??? // ???
*(AuUInt32 *)0 = exitcode; *(AuUInt32 *)0 = exitcode;

View File

@ -26,6 +26,11 @@
#include "SpawnThread.hpp" #include "SpawnThread.hpp"
namespace Aurora
{
void RuntimeLateClean();
}
namespace Aurora::Threading::Threads namespace Aurora::Threading::Threads
{ {
static struct DtorFlipper static struct DtorFlipper
@ -49,6 +54,7 @@ namespace Aurora::Threading::Threads
static void HandleSigAbortThread(int a) static void HandleSigAbortThread(int a)
{ {
((OSThread *)HandleCurrent())->InternalKill(true);
((OSThread *)HandleCurrent())->InternalKillForceNtfy(); ((OSThread *)HandleCurrent())->InternalKillForceNtfy();
SysPanic("Couldn't terminate thread context"); SysPanic("Couldn't terminate thread context");
} }
@ -96,12 +102,12 @@ namespace Aurora::Threading::Threads
return; return;
} }
if (DeadTest()) if (!gGlobal.bActive)
{ {
return; return;
} }
if (!gGlobal.bActive) if (DeadTest())
{ {
return; return;
} }
@ -118,18 +124,23 @@ namespace Aurora::Threading::Threads
{ {
Exit(); Exit();
} }
else if (gRuntimeRunLevel >= 5)
{
// Application is dead
}
else else
{ {
if (RuntimeIsMainThread())
{
HookReleaseThreadResources();
return;
}
// Kill the current OS thread instance // Kill the current OS thread instance
TeminateOSContext(false); TeminateOSContext(false);
if (this->exitOnlyOnce_)
// Dispatch kill callback from within an emulated thread context (no switch, just just change thread tls)
ExecuteInDeadThread([=]()
{ {
this->InternalKill(true); this->exitOnlyOnce_->Unlock();
}); }
this->exitOnlyOnce_->Unlock();
} }
if (gRuntimeRunLevel < 4) // minimum: async deinit level if (gRuntimeRunLevel < 4) // minimum: async deinit level
@ -290,6 +301,11 @@ namespace Aurora::Threading::Threads
return true; return true;
} }
if (!this->exitOnlyOnce_)
{
return true;
}
// attempt to join with the thread once it has exited, or timeout // attempt to join with the thread once it has exited, or timeout
if (WaitFor(this->terminated_.get(), 15 * 1000)) if (WaitFor(this->terminated_.get(), 15 * 1000))
{ {
@ -425,6 +441,7 @@ namespace Aurora::Threading::Threads
// TODO: we need an internal OSThread *TryPokeTLSThread() // TODO: we need an internal OSThread *TryPokeTLSThread()
auto osThread = static_cast<OSThread *>(GetThread()); auto osThread = static_cast<OSThread *>(GetThread());
this->tlsReferenceThread_ = osThread; this->tlsReferenceThread_ = osThread;
bool bFailing {};
OSAttach(); OSAttach();
try try
@ -444,12 +461,30 @@ namespace Aurora::Threading::Threads
#else #else
catch (...) catch (...)
{ {
bFailing = true;
if (!Aurora::kIsDebugBuild) if (!Aurora::kIsDebugBuild)
{ {
SysPushErrorHAL("OS Thread Aborted"); SysPushErrorHAL("OS Thread Aborted");
} }
// "Safer" update
this->HookOnExit();
if (this->terminated_)
{
this->exitOnlyOnce_->Unlock();
this->terminated_->Set();
}
if (this->terminatedSignalLs_)
{
this->terminatedSignalLs_->Set();
}
}
if (!bFailing)
{
Exit(true); Exit(true);
throw; // bc c-world cant be compatible bc free-iq half-assed software
} }
#endif #endif
} }
@ -933,6 +968,11 @@ namespace Aurora::Threading::Threads
{ {
if (!locked) if (!locked)
{ {
if (!this->exitOnlyOnce_)
{
return true;
}
if (!this->exitOnlyOnce_->TryLock()) if (!this->exitOnlyOnce_->TryLock())
{ {
return false; return false;
@ -991,8 +1031,15 @@ namespace Aurora::Threading::Threads
// Great C++ ABI guys... // Great C++ ABI guys...
#if defined(AURORA_HAS_PTHREADS) #if defined(AURORA_HAS_PTHREADS)
::longjmp(env, 1); if (!AuExchange(bLongJmpOnce, true))
::pthread_exit(nullptr); {
::longjmp(env, 1);
}
else
{
}
//::pthread_exit(nullptr);
#endif #endif
return true; return true;
@ -1020,8 +1067,15 @@ namespace Aurora::Threading::Threads
if (calledFromThis) if (calledFromThis)
{ {
::longjmp(env, 1); if (!AuExchange(bLongJmpOnce, true))
::pthread_exit(nullptr); {
::longjmp(env, 1);
}
else
{
}
//::pthread_exit(nullptr);
} }
else else
{ {

View File

@ -52,6 +52,7 @@ namespace Aurora::Threading::Threads
AuSPtr<AuLoop::ILoopSource> GetShutdownSignalLS() override; AuSPtr<AuLoop::ILoopSource> GetShutdownSignalLS() override;
bool InternalKillForceNtfy(); bool InternalKillForceNtfy();
bool InternalKill(bool locked);
protected: protected:
bool Exit(bool willReturnToOS, bool isEOL = false); bool Exit(bool willReturnToOS, bool isEOL = false);
@ -61,7 +62,6 @@ namespace Aurora::Threading::Threads
void UpdateName(); void UpdateName();
void OSAttach(); void OSAttach();
void OSDeatach(); void OSDeatach();
bool InternalKill(bool locked);
void TeminateOSContext(bool calledFromThis); void TeminateOSContext(bool calledFromThis);
void FreeOSContext(); void FreeOSContext();
@ -90,6 +90,7 @@ namespace Aurora::Threading::Threads
Primitives::EventShared_t terminateSignal_; Primitives::EventShared_t terminateSignal_;
AuSPtr<AuLoop::ILSEvent> terminateSignalLs_; AuSPtr<AuLoop::ILSEvent> terminateSignalLs_;
AuSPtr<AuLoop::ILSEvent> terminatedSignalLs_; AuSPtr<AuLoop::ILSEvent> terminatedSignalLs_;
bool bLongJmpOnce {};
Primitives::CriticalSectionUnique_t exitOnlyOnce_; Primitives::CriticalSectionUnique_t exitOnlyOnce_;