[*] 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()
{
this->End();
this->HistoryAppendChanges();
}
@ -76,7 +77,15 @@ namespace Aurora::Console::ConsoleTTY
void TTYConsole::End()
{
gTTYConsoleEnabled = false;
if (!AuExchange(gTTYConsoleEnabled, false))
{
return;
}
if (NoncanonicalMode())
{
ConsoleStd::LeaveNoncanonicalMode();
}
TTYClearScreen();
TTYClearLine(EAnsiColor::eReset);
@ -85,11 +94,6 @@ namespace Aurora::Console::ConsoleTTY
TTYWrite("\033[?1049l");
#endif
if (NoncanonicalMode())
{
ConsoleStd::LeaveNoncanonicalMode();
}
#if defined(AURORA_IS_MODERNNT_DERIVED)
SetConsoleOutputCP(this->oldCP);
#endif
@ -98,6 +102,11 @@ namespace Aurora::Console::ConsoleTTY
{
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)

View File

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

View File

@ -13,6 +13,7 @@
#include <dlfcn.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>
#endif
#if defined(AURORA_PLATFORM_WIN32)
@ -548,7 +549,12 @@ namespace Aurora::Process
#if defined(AURORA_IS_MODERNNT_DERIVED)
ExitProcess(exitcode);
#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
// ???
*(AuUInt32 *)0 = exitcode;

View File

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

View File

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