summaryrefslogtreecommitdiffstats
path: root/src/corelib/io
diff options
context:
space:
mode:
authorMiikka Heikkinen <miikka.heikkinen@digia.com>2010-08-16 13:09:34 (GMT)
committerMiikka Heikkinen <miikka.heikkinen@digia.com>2010-08-16 13:58:34 (GMT)
commit7cfc9f2245162944f3d9a29ad73cd93e2bcf197f (patch)
tree3e8c9a26ed980702ea0f87a25a181bbd773612b7 /src/corelib/io
parent881b3bf8212432590d19e2a979577c2a9f3ab80b (diff)
downloadQt-7cfc9f2245162944f3d9a29ad73cd93e2bcf197f.zip
Qt-7cfc9f2245162944f3d9a29ad73cd93e2bcf197f.tar.gz
Qt-7cfc9f2245162944f3d9a29ad73cd93e2bcf197f.tar.bz2
Fix QProcessManager destruction
If QProcessManager destructor is ran as part of global static cleanup, manager thread will most likely be terminated by kernel at that point, so trying to delete QProcessActives and QProcessMediators will panic as they will still be active. They can also no longer be properly canceled as the thread is already gone. In case manager thread has already died, which implies that process exit is imminent, we simply do nothing and let the deletion of the main heap at process exit take care of stray objects. Task-number: QTBUG-11218 Reviewed-by: Janne Koskinen
Diffstat (limited to 'src/corelib/io')
-rw-r--r--src/corelib/io/qprocess_symbian.cpp47
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();
}