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_;