diff options
Diffstat (limited to 'src/corelib')
-rw-r--r-- | src/corelib/io/qprocess_symbian.cpp | 47 |
1 files changed, 28 insertions, 19 deletions
diff --git a/src/corelib/io/qprocess_symbian.cpp b/src/corelib/io/qprocess_symbian.cpp index af657b2..003e781 100644 --- a/src/corelib/io/qprocess_symbian.cpp +++ b/src/corelib/io/qprocess_symbian.cpp @@ -375,10 +375,9 @@ QProcessActive::QProcessActive() // Nothing to do } -// Called from ProcessManagerThread +// Called from main thread QProcessActive::~QProcessActive() { - Cancel(); process = NULL; pproc = NULL; } @@ -482,10 +481,9 @@ QProcessManagerMediator::QProcessManagerMediator() // Nothing to do } -// Called from ProcessManagerThread +// Called from main thread QProcessManagerMediator::~QProcessManagerMediator() { - Cancel(); processManagerThread.Close(); currentCommand = ENoCommand; currentObserver = NULL; @@ -648,25 +646,36 @@ QProcessManager::QProcessManager() QProcessManager::~QProcessManager() { QPROCESS_DEBUG_PRINT("QProcessManager::~QProcessManager()"); - // Cancel death listening for all child processes - if (mediator) { - QMap<int, QProcessActive *>::Iterator it = children.begin(); - while (it != children.end()) { - // Remove all monitors - QProcessActive *active = it.value(); - mediator->remove(active); - - QPROCESS_DEBUG_PRINT("QProcessManager::~QProcessManager() removed listening for a process"); - ++it; + + // Check if manager thread is still alive. If this destructor is ran as part of global + // static cleanup, manager thread will most likely be terminated by kernel at this point, + // so trying to delete QProcessActives and QProcessMediators will panic as they + // will still be active. They can also no longer be canceled as the thread is already gone. + // In case manager thread has already died, we simply do nothing and let the deletion of + // the main heap at process exit take care of stray objects. + + if (managerThread.Handle() && managerThread.ExitType() == EExitPending) { + // Cancel death listening for all child processes + if (mediator) { + QMap<int, QProcessActive *>::Iterator it = children.begin(); + while (it != children.end()) { + // Remove all monitors + QProcessActive *active = it.value(); + mediator->remove(active); + + QPROCESS_DEBUG_PRINT("QProcessManager::~QProcessManager() removed listening for a process"); + ++it; + } + + // Terminate process manager thread. + mediator->terminate(); + delete mediator; } - // Terminate process manager thread. - mediator->terminate(); - delete mediator; + qDeleteAll(children.values()); + children.clear(); } - qDeleteAll(children.values()); - children.clear(); managerThread.Close(); managerMutex.Close(); } |