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); DCFlushRange(&instance, 4);
} }
} }
static void destroyInstance(bool forceKill) {
if (instance != nullptr) {
instance->skipJoin = true;
}
destroyInstance();
}
BackgroundThread(); BackgroundThread();

View File

@ -56,7 +56,9 @@ ON_APPLICATION_START() {
initLogging(); initLogging();
//Make sure the server instance is destroyed. //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) { if (gFTPServerEnabled) {
startServer(); startServer();
} }

View File

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