From e976774d527933335c13fcb44d32d3bb10153765 Mon Sep 17 00:00:00 2001
From: "Uwe L. Korn" <uwelk@xhochy.com>
Date: Fri, 14 Jun 2013 12:23:04 +0200
Subject: [PATCH] Only invoke Closure if receiver still exists

---
 src/libtomahawk/utils/Closure.cpp | 37 ++++++++++++++++++++-----------
 src/libtomahawk/utils/Closure.h   |  3 ++-
 2 files changed, 26 insertions(+), 14 deletions(-)

diff --git a/src/libtomahawk/utils/Closure.cpp b/src/libtomahawk/utils/Closure.cpp
index e77321d5d..e1d7be6b0 100644
--- a/src/libtomahawk/utils/Closure.cpp
+++ b/src/libtomahawk/utils/Closure.cpp
@@ -80,20 +80,31 @@ void Closure::Connect(QObject* sender, const char* signal) {
   Q_UNUSED(success);
 }
 
-void Closure::Invoked() {
-  if (callback_) {
-    callback_();
-  } else {
-    slot_.invoke(
-        parent() ? parent() : outOfThreadReceiver_,
-        val0_ ? val0_->arg() : QGenericArgument(),
-        val1_ ? val1_->arg() : QGenericArgument(),
-        val2_ ? val2_->arg() : QGenericArgument(),
-        val3_ ? val3_->arg() : QGenericArgument());
-  }
+void
+Closure::Invoked() {
+    if ( callback_ )
+    {
+        callback_();
+    }
+    else
+    {
+        // Only invoke the closure if the receiver still exists
+        // Hint: If parent was destroyed, this closure would also be destroyed
+        if ( parent() || !outOfThreadReceiver_.isNull() )
+        {
+            slot_.invoke(
+                parent() ? parent() : outOfThreadReceiver_.data(),
+                val0_ ? val0_->arg() : QGenericArgument(),
+                val1_ ? val1_->arg() : QGenericArgument(),
+                val2_ ? val2_->arg() : QGenericArgument(),
+                val3_ ? val3_->arg() : QGenericArgument());
+        }
+    }
 
-  if ( autoDelete_ )
-    deleteLater();
+    if ( autoDelete_ )
+    {
+        deleteLater();
+    }
 }
 
 void Closure::Cleanup() {
diff --git a/src/libtomahawk/utils/Closure.h b/src/libtomahawk/utils/Closure.h
index fa89257d5..6008f62ed 100644
--- a/src/libtomahawk/utils/Closure.h
+++ b/src/libtomahawk/utils/Closure.h
@@ -31,6 +31,7 @@ using std::tr1::function;
 
 #include <QMetaMethod>
 #include <QObject>
+#include <QPointer>
 #include <QSharedPointer>
 
 #include <boost/noncopyable.hpp>
@@ -95,7 +96,7 @@ class DLLEXPORT Closure : public QObject, boost::noncopyable {
   QMetaMethod slot_;
   function<void()> callback_;
   bool autoDelete_;
-  QObject* outOfThreadReceiver_;
+  QPointer<QObject> outOfThreadReceiver_;
 
   boost::scoped_ptr<const ClosureArgumentWrapper> val0_;
   boost::scoped_ptr<const ClosureArgumentWrapper> val1_;