Fix some QtDBus crashes during application destruction

It's possible that some code executes after QDBusConnectionManager is
destroyed and still tries to access QtDBus. Protect against such
crashes.

Change-Id: I87e17314d8b24ae983b1fffd1453c13fbd3cf48e
Reviewed-by: René J.V. Bertin <rjvbertin@gmail.com>
Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@qt.io>
This commit is contained in:
Thiago Macieira 2016-05-31 17:33:03 -03:00 committed by Jani Heikkinen
parent daeb334039
commit 67f466505e
3 changed files with 21 additions and 6 deletions

View File

@ -426,7 +426,7 @@ void QDBusConnectionManager::createServer(const QString &address, void *server)
*/
QDBusConnection::QDBusConnection(const QString &name)
{
if (name.isEmpty()) {
if (name.isEmpty() || _q_manager.isDestroyed()) {
d = 0;
} else {
QMutexLocker locker(&_q_manager()->mutex);
@ -491,7 +491,7 @@ QDBusConnection &QDBusConnection::operator=(const QDBusConnection &other)
*/
QDBusConnection QDBusConnection::connectToBus(BusType type, const QString &name)
{
if (!qdbus_loadLibDBus()) {
if (_q_manager.isDestroyed() || !qdbus_loadLibDBus()) {
QDBusConnectionPrivate *d = 0;
return QDBusConnection(d);
}
@ -505,7 +505,7 @@ QDBusConnection QDBusConnection::connectToBus(BusType type, const QString &name)
QDBusConnection QDBusConnection::connectToBus(const QString &address,
const QString &name)
{
if (!qdbus_loadLibDBus()) {
if (_q_manager.isDestroyed() || !qdbus_loadLibDBus()) {
QDBusConnectionPrivate *d = 0;
return QDBusConnection(d);
}
@ -520,7 +520,7 @@ QDBusConnection QDBusConnection::connectToBus(const QString &address,
QDBusConnection QDBusConnection::connectToPeer(const QString &address,
const QString &name)
{
if (!qdbus_loadLibDBus()) {
if (_q_manager.isDestroyed() || !qdbus_loadLibDBus()) {
QDBusConnectionPrivate *d = 0;
return QDBusConnection(d);
}
@ -1175,6 +1175,8 @@ bool QDBusConnection::unregisterService(const QString &serviceName)
*/
QDBusConnection QDBusConnection::sessionBus()
{
if (_q_manager.isDestroyed())
return QDBusConnection(Q_NULLPTR);
return QDBusConnection(_q_manager()->busConnection(SessionBus));
}
@ -1187,6 +1189,8 @@ QDBusConnection QDBusConnection::sessionBus()
*/
QDBusConnection QDBusConnection::systemBus()
{
if (_q_manager.isDestroyed())
return QDBusConnection(Q_NULLPTR);
return QDBusConnection(_q_manager()->busConnection(SystemBus));
}

View File

@ -299,6 +299,9 @@ static void qDBusNewConnection(DBusServer *server, DBusConnection *connection, v
Q_ASSERT(connection);
Q_ASSERT(data);
if (!QDBusConnectionManager::instance())
return;
// keep the connection alive
q_dbus_connection_ref(connection);
QDBusConnectionPrivate *serverConnection = static_cast<QDBusConnectionPrivate *>(data);

View File

@ -68,7 +68,11 @@ QDBusServer::QDBusServer(const QString &address, QObject *parent)
if (!qdbus_loadLibDBus())
return;
emit QDBusConnectionManager::instance()->serverRequested(address, this);
QDBusConnectionManager *instance = QDBusConnectionManager::instance();
if (!instance)
return;
emit instance->serverRequested(address, this);
QObject::connect(d, SIGNAL(newServerConnection(QDBusConnectionPrivate*)),
this, SLOT(_q_newConnection(QDBusConnectionPrivate*)), Qt::QueuedConnection);
}
@ -93,7 +97,11 @@ QDBusServer::QDBusServer(QObject *parent)
return;
}
emit QDBusConnectionManager::instance()->serverRequested(address, this);
QDBusConnectionManager *instance = QDBusConnectionManager::instance();
if (!instance)
return;
emit instance->serverRequested(address, this);
QObject::connect(d, SIGNAL(newServerConnection(QDBusConnectionPrivate*)),
this, SLOT(_q_newConnection(QDBusConnectionPrivate*)), Qt::QueuedConnection);
}