[*] Fix: Termination of Linux C++ code without C++ land whining about NPTL no-rethrow

This commit is contained in:
Reece Wilson 2022-08-06 20:50:40 +01:00
parent 9c90e96dee
commit 331f139fdd
2 changed files with 61 additions and 25 deletions

View File

@ -44,14 +44,15 @@ namespace Aurora::Threading::Threads
static ThreadInfo gDummyThreadInfo;
#if defined(AURORA_IS_UNIX_DERIVED)
static const auto kSignalAbort = 77;
#if defined(AURORA_IS_POSIX_DERIVED)
static const auto kSignalAbort = SIGUSR1;
static void HandleSigAbortThread(int a)
{
pthread_exit(nullptr);
((OSThread *)HandleCurrent())->InternalKillForceNtfy();
SysPanic("Couldn't terminate thread context");
}
#endif
OSThread::OSThread(const ThreadInfo &info) : info_(info)
@ -513,6 +514,18 @@ namespace Aurora::Threading::Threads
#endif
}
static void AttachSignalKiller()
{
#if defined(AURORA_IS_POSIX_DERIVED)
struct sigaction action =
{
.sa_handler = HandleSigAbortThread,
};
::sigemptyset(&action.sa_mask);
::sigaction(kSignalAbort, &action, nullptr);
#endif
}
void OSThread::OSAttach()
{
this->bSupportsAltKill = true;
@ -536,21 +549,17 @@ namespace Aurora::Threading::Threads
this->unixThreadId_ = 0; // !!!!
#endif
#if defined(AURORA_IS_POSIX_DERIVED)
if (setjmp(env) != 0)
{
pthread_exit(nullptr);
}
#endif
UpdatePrio(this->throttle_, this->prio_);
SetAffinity(this->mask_);
UpdateName();
// TODO: rushed
#if defined(AURORA_IS_UNIX_DERIVED)
struct sigaction action =
{
.sa_handler = HandleSigAbortThread,
.sa_flags = SA_ONSTACK
};
::sigemptyset(&action.sa_mask);
::sigaction(kSignalAbort, &action, nullptr);
#endif
AttachSignalKiller();
}
static AuHashMap<EThreadPriority, int> kNiceMap
@ -870,13 +879,12 @@ namespace Aurora::Threading::Threads
void OSThread::OSDeatach()
{
#if defined(AURORA_IS_UNIX_DERIVED)
#if defined(AURORA_IS_POSIX_DERIVED)
struct sigaction action =
{
.sa_handler = SIG_DFL
};
::sigemptyset(&action.sa_mask);
::sigaction(kSignalAbort, &action, nullptr);
#endif
}
@ -920,7 +928,6 @@ namespace Aurora::Threading::Threads
{
this->exitOnlyOnce_->Unlock();
this->terminated_->Set();
}
if (this->terminatedSignalLs_)
@ -931,6 +938,25 @@ namespace Aurora::Threading::Threads
return true;
}
bool OSThread::InternalKillForceNtfy()
{
if (this->terminated_)
{
this->exitOnlyOnce_->Unlock();
this->terminated_->Set();
}
if (this->terminatedSignalLs_)
{
this->terminatedSignalLs_->Set();
}
::longjmp(env, 1);
::pthread_exit(nullptr);
return true;
}
void OSThread::TeminateOSContext(bool calledFromThis)
{
#if defined(AURORA_IS_MODERNNT_DERIVED)
@ -942,19 +968,19 @@ namespace Aurora::Threading::Threads
if (calledFromThis)
{
ExitThread(0);
::ExitThread(0);
}
else
{
TerminateThread(this->handle_, 0);
::TerminateThread(this->handle_, 0);
}
#elif defined(AURORA_HAS_PTHREADS)
// TODO (Reece): urgent
if (false && calledFromThis) // this works. leave it.
if (calledFromThis)
{
pthread_exit(nullptr);
::longjmp(env, 1);
::pthread_exit(nullptr);
}
else
{
@ -969,11 +995,11 @@ namespace Aurora::Threading::Threads
if (this->bSupportsAltKill)
{
pthread_kill(this->handle_, 77);
::pthread_kill(this->handle_, kSignalAbort);
}
else
{
pthread_cancel(this->handle_);
::pthread_cancel(this->handle_);
}
}
@ -1011,5 +1037,6 @@ namespace Aurora::Threading::Threads
#if defined(AURORA_PLATFORM_WIN32)
AuxUlibInitialize();
#endif
AttachSignalKiller();
}
}

View File

@ -7,6 +7,10 @@
***/
#pragma once
#if defined(AURORA_IS_POSIX_DERIVED)
#include <setjmp.h>
#endif
namespace Aurora::Threading::Threads
{
struct OSThread : IAuroraThread
@ -45,6 +49,8 @@ namespace Aurora::Threading::Threads
AuSPtr<AuLoop::ILoopSource> AsLoopSource() override;
AuSPtr<IWaitable> GetShutdownSignalWaitable() override;
AuSPtr<AuLoop::ILoopSource> GetShutdownSignalLS() override;
bool InternalKillForceNtfy();
protected:
bool Exit(bool willReturnToOS, bool isEOL = false);
@ -62,6 +68,9 @@ namespace Aurora::Threading::Threads
void HookOnExit();
private:
#if defined(AURORA_IS_POSIX_DERIVED)
jmp_buf env;
#endif
Primitives::SpinLock tlsLock_;
AuSPtr<TLSView> tls_;
OSThread * tlsReferenceThread_ {};