diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2015-09-23 14:08:52 -0700 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@theqtcompany.com> | 2015-09-25 07:45:06 +0000 |
commit | 58d9b42c03672a21b4976b69b06915af1352d78a (patch) | |
tree | 72cf965a7b35911b8cd8b8aaed547f5f53b91d10 /src/dbus/qdbusintegrator.cpp | |
parent | c9697677f4bd8e94f5367deab540b90e60e898a5 (diff) |
Fix deadlock on disconnectNotify() called from ~QObject
Normally, disconnectNotify() is called at the end of QObject::disconnect
and all the locks have been dropped. That is not the case for the
QObject destructor, so we need to deal with the fact that it there may
be some locks held.
I didn't catch this issue during testing because it depends on the
pointer addresses of the object being destroyed and that of the
QDBusAbstractInterface sender object, as we use one global, non-
recursive mutex pool. For the same reason, this patch is not testable.
The fix is simple: we don't need to remove the relay rules immediately.
It's ok for them to happen later, since the worst case scenario is that
we'll receive a few more signals than we have objects to deliver them
to. If that happens, we'll do a little more work than we have to. But in
the normal case, the amount of work is the same and we get the benefit
of returning more quickly from the destructor. What's more, if the
QDBusAbstractInterface object also gets destroyed, the events are
deleted and QDBusConnectionPrivate will clean everything up.
Task-number: QTBUG-48410
Change-Id: I42e7ef1a481840699a8dffff1406b789ba5217b3
Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
Diffstat (limited to 'src/dbus/qdbusintegrator.cpp')
-rw-r--r-- | src/dbus/qdbusintegrator.cpp | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index 7203f05a9b..c465706913 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -2278,7 +2278,7 @@ void QDBusConnectionPrivate::disconnectRelay(const QString &service, sig.append(signal.methodSignature()); if (!prepareHook(hook, key, service, path, interface, QString(), QStringList(), receiver, sig, QDBusAbstractInterface::staticMetaObject.methodCount(), true)) - return; // don't connect + return; // don't disconnect Q_ASSERT(thread() != QThread::currentThread()); emit signalNeedsDisconnecting(key, hook); |