[*] Various teardown related fixes/changes under UNIX
This commit is contained in:
parent
0fe4ad2087
commit
7fd217a50e
@ -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)
|
||||||
|
@ -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)
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
{
|
{
|
||||||
|
@ -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_;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user