Fix potential softlock that could happen if the thread was canceled but is not (marked as) terminated

This commit is contained in:
Maschell 2022-10-06 12:00:52 +02:00
parent 9b64c3bb51
commit 2a79fd7862
3 changed files with 24 additions and 10 deletions

View File

@ -23,6 +23,12 @@ public:
DCFlushRange(&instance, 4);
}
}
static void destroyInstance(bool forceKill) {
if (instance != nullptr) {
instance->skipJoin = true;
}
destroyInstance();
}
BackgroundThread();

View File

@ -56,7 +56,9 @@ ON_APPLICATION_START() {
initLogging();
//Make sure the server instance is destroyed.
BackgroundThread::destroyInstance();
// Skipping joining the thread as it's not even running at this point but still may be allocated.
BackgroundThread::destroyInstance(true);
thread = nullptr;
if (gFTPServerEnabled) {
startServer();
}

View File

@ -101,16 +101,20 @@ public:
//! Shutdown thread
virtual void shutdownThread() {
//! wait for thread to finish
if (pThread && !(iAttributes & eAttributeDetach)) {
if (!isThreadTerminated()) {
if (isThreadSuspended()) {
resumeThread();
}
if (skipJoin) {
DEBUG_FUNCTION_LINE_WARN("Skip joining the thread \"%s\", it's not running.", pThreadName.c_str());
} else {
//! wait for thread to finish
if (pThread && !(iAttributes & eAttributeDetach)) {
if (!isThreadTerminated()) {
if (isThreadSuspended()) {
resumeThread();
}
OSJoinThread(pThread, nullptr);
} else {
DEBUG_FUNCTION_LINE_WARN("Thread \"%s\" has already been terminated!!!", pThreadName.c_str());
OSJoinThread(pThread, nullptr);
} else {
DEBUG_FUNCTION_LINE_WARN("Thread \"%s\" has already been terminated!!!", pThreadName.c_str());
}
}
}
//! free the thread stack buffer
@ -135,6 +139,8 @@ public:
eAttributePinnedAff = 0x10
};
bool skipJoin = false;
private:
static int threadCallback(int argc, const char **argv) {
//! After call to start() continue with the internal function