Browse Source

Fixed memory leak due to a shared pointer cycle.

Sascha Zelzer 13 years ago
parent
commit
af55ea5983

+ 7 - 5
Libs/PluginFramework/ctkPluginFramework.cpp

@@ -72,20 +72,22 @@ ctkPluginFrameworkEvent ctkPluginFramework::waitForStop(unsigned long timeout)
   // Already stopped?
   if ((d->state & (INSTALLED | RESOLVED)) == 0)
   {
-    d->stopEvent = ctkPluginFrameworkEvent();
+    d->stopEvent.isNull = true;
     d->lock.wait(timeout ? timeout : ULONG_MAX);
 
-    if (d->stopEvent.isNull())
+    if (d->stopEvent.isNull)
     {
       return ctkPluginFrameworkEvent(ctkPluginFrameworkEvent::FRAMEWORK_WAIT_TIMEDOUT, this->d_func()->q_func());
     }
   }
-  else if (d->stopEvent.isNull())
+  else if (d->stopEvent.isNull)
   {
     // Return this if stop or update have not been called and framework is stopped.
-    d->stopEvent = ctkPluginFrameworkEvent(ctkPluginFrameworkEvent::FRAMEWORK_STOPPED, this->d_func()->q_func());
+    d->stopEvent.isNull = false;
+    d->stopEvent.type = ctkPluginFrameworkEvent::FRAMEWORK_STOPPED;
   }
-  return d->stopEvent;
+  return d->stopEvent.isNull ? ctkPluginFrameworkEvent() :
+                               ctkPluginFrameworkEvent(ctkPluginFrameworkEvent::FRAMEWORK_STOPPED, this->d_func()->q_func());
 }
 
 //----------------------------------------------------------------------------

+ 2 - 1
Libs/PluginFramework/ctkPluginFrameworkPrivate.cpp

@@ -214,5 +214,6 @@ void ctkPluginFrameworkPrivate::systemShuttingdownDone_unlocked(const ctkPluginF
     operation.fetchAndStoreOrdered(IDLE);
     lock.wakeAll();
   }
-  stopEvent = fe;
+  stopEvent.isNull = fe.isNull();
+  stopEvent.type = fe.getType();
 }

+ 13 - 1
Libs/PluginFramework/ctkPluginFrameworkPrivate_p.h

@@ -37,10 +37,22 @@ class ctkPluginFrameworkPrivate : public ctkPluginPrivate
 public:
 
   /**
+   * Holds all information for constructing a ctkPluginFrameworkEvent instance,
+   * except for holding a QSharedPointer to the framework plug-in. This avoids
+   * cyclic references in ctkPluginFramework.
+   */
+  struct FWEventWrapper
+  {
+    FWEventWrapper() : isNull(true) {}
+    bool isNull;
+    ctkPluginFrameworkEvent::Type type;
+  };
+
+  /**
    * The event to return to callers waiting in ctkPluginFramework::waitForStop()
    * when the framework has been stopped.
    */
-  ctkPluginFrameworkEvent stopEvent;
+  FWEventWrapper stopEvent;
 
   /**
    * The flag indicating that the thread that performs shutdown of this