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,6 +101,9 @@ public:
//! Shutdown thread //! Shutdown thread
virtual void shutdownThread() { virtual void shutdownThread() {
if (skipJoin) {
DEBUG_FUNCTION_LINE_WARN("Skip joining the thread \"%s\", it's not running.", pThreadName.c_str());
} else {
//! wait for thread to finish //! wait for thread to finish
if (pThread && !(iAttributes & eAttributeDetach)) { if (pThread && !(iAttributes & eAttributeDetach)) {
if (!isThreadTerminated()) { if (!isThreadTerminated()) {
@ -113,6 +116,7 @@ public:
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
if (pThreadStack) { if (pThreadStack) {
free(pThreadStack); free(pThreadStack);
@ -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