From 72ecf5a7ecb688a7e19cbc2f70e358a94d02edf7 Mon Sep 17 00:00:00 2001 From: Peter Seiderer Date: Mon, 17 Jun 2013 20:56:08 +0200 Subject: Remove QDBusPendingCallPrivate::autoDelete logic. First step to fix race condition about deleting QDBusPendingCallPrivate. In a multithreaded application on a slow/single core cpu the following race (and segmentation fault) can occur: First thread A is running: A: QDBusPendingReply<> reply = pi->asyncCallWithArgumentList(method, argumentList); Then when the dbus answer arrives thread B will call: B: QDBusConnectionPrivate::processFinishedCall() B: ... B: locker.unlock() and runs until here, go on with thread A: A: reply.waitForFinished(); A: QDBusPendingCallPrivate::waitForFinished() A: { A: QMutexLocker locker(&mutex); A: if (replyMessage.type() != QDBusMessage::InvalidMessage) A: return; which returns immediately (mutex acquired, replyMessage alread set), now reply goes out of scope (destructor called) and QDBusPendingCall::d's destructor of type QExplicitlySharedDataPointer deletes the reference counted object QDBusPendingCallPrivate. Now thread B continues, still in processFinishedCall() B: if (call->watcherHelper) B: call->watcherHelper->emitSignals(msg, call->sentMessage); B: B: if (msg.type() == QDBusMessage::ErrorMessage) B: emit connection->callWithCallbackFailed(QDBusError(msg), B: call->sentMessage); accessing alread deleted object QDBusPendingCallPrivate via call->... Fixed QDBusPendingCallPrivate deletion by proper reference counting will be done in the next commit. Task-number: QTBUG-27809 Change-Id: I15b3f0242471b62eaafadc763fb6a33339ff2fe1 Reviewed-by: Thiago Macieira --- src/dbus/qdbuspendingcall_p.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/dbus/qdbuspendingcall_p.h') diff --git a/src/dbus/qdbuspendingcall_p.h b/src/dbus/qdbuspendingcall_p.h index 36d0b9023a..d0b28b3c0e 100644 --- a/src/dbus/qdbuspendingcall_p.h +++ b/src/dbus/qdbuspendingcall_p.h @@ -85,7 +85,6 @@ public: QVector metaTypes; int methodIdx; - bool autoDelete; // } mutable QMutex mutex; @@ -102,7 +101,7 @@ public: // } QDBusPendingCallPrivate(const QDBusMessage &sent, QDBusConnectionPrivate *connection) - : sentMessage(sent), connection(connection), autoDelete(false), watcherHelper(0), pending(0), waitingForFinished(false) + : sentMessage(sent), connection(connection), watcherHelper(0), pending(0), waitingForFinished(false) { } ~QDBusPendingCallPrivate(); bool setReplyCallback(QObject *target, const char *member); -- cgit v1.2.3