fix memory leak of QLibraryPrivate
authorjian liang <jianliang79@gmail.com>
Sun, 22 Jan 2012 14:38:49 +0000 (22:38 +0800)
committerQt by Nokia <qt-info@nokia.com>
Tue, 7 Feb 2012 11:48:06 +0000 (12:48 +0100)
this commit is aimed to fix QTBUG-4341. now QFactoryLoaderPrivate's
destructor will call unload() to QLibaryPrivate object which will destory
the plugin's root instance if its refcount reach zero.

Task-number: QTBUG-4341
Change-Id: I3cd3e071b34271bf5802ab09f6c125beda5e9844
Reviewed-by: Robin Burchell <robin+qt@viroteck.net>
Reviewed-by: David Faure <faure@kde.org>
Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
src/corelib/plugin/qfactoryloader.cpp

index e887ae8..fe5aea0 100644 (file)
@@ -78,8 +78,11 @@ public:
 
 QFactoryLoaderPrivate::~QFactoryLoaderPrivate()
 {
-    for (int i = 0; i < libraryList.count(); ++i)
-        libraryList.at(i)->release();
+    for (int i = 0; i < libraryList.count(); ++i) {
+        QLibraryPrivate *library = libraryList.at(i);
+        library->unload();
+        library->release();
+    }
 }
 
 QFactoryLoader::QFactoryLoader(const char *iid,
@@ -142,7 +145,10 @@ void QFactoryLoader::update()
                 library->release();
                 continue;
             }
-            QObject *instance = library->instance();
+
+            if (!library->inst)
+                library->inst = library->instance();
+            QObject *instance = library->inst.data();
             if (!instance) {
                 library->release();
                 // ignore plugins that have a valid signature but cannot be loaded.
@@ -215,8 +221,11 @@ QObject *QFactoryLoader::instance(const QString &key) const
     QString lowered = d->cs ? key : key.toLower();
     if (QLibraryPrivate* library = d->keyMap.value(lowered)) {
         if (library->instance || library->loadPlugin()) {
-            if (QObject *obj = library->instance()) {
-                if (obj && !obj->parent())
+            if (!library->inst)
+                library->inst = library->instance();
+            QObject *obj = library->inst.data();
+            if (obj) {
+                if (!obj->parent())
                     obj->moveToThread(QCoreApplicationPrivate::mainThread());
                 return obj;
             }