Skip to content

Commit

Permalink
QDBusServer: delay processing of D-Bus messages
Browse files Browse the repository at this point in the history
We must ensure that QDBusServer's newConnection() signal has been
processed by the application, before starting processing messages on it.

Task-number: QTBUG-55087
Change-Id: I595329b2f98788dbf9f40558b8c230c0c0817ef8
Reviewed-by: Timo Jyrinki <timo.jyrinki@iki.fi>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
  • Loading branch information
mardy authored and martinjones committed Oct 3, 2016
1 parent 50989ad commit d419f77
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 20 deletions.
20 changes: 0 additions & 20 deletions src/dbus/qdbusconnection.cpp
Expand Up @@ -68,24 +68,6 @@ static void preventDllUnload();

Q_GLOBAL_STATIC(QDBusConnectionManager, _q_manager)

// can be replaced with a lambda in Qt 5.7
class QDBusConnectionDispatchEnabler : public QObject
{
Q_OBJECT
QDBusConnectionPrivate *con;
public:
QDBusConnectionDispatchEnabler(QDBusConnectionPrivate *con) : con(con) {}

public slots:
void execute()
{
con->setDispatchEnabled(true);
if (!con->ref.deref())
con->deleteLater();
deleteLater();
}
};

struct QDBusConnectionManager::ConnectionRequestData
{
enum RequestType {
Expand Down Expand Up @@ -1281,8 +1263,6 @@ QByteArray QDBusConnection::localMachineId()

QT_END_NAMESPACE

#include "qdbusconnection.moc"

#ifdef Q_OS_WIN
# include <qt_windows.h>

Expand Down
19 changes: 19 additions & 0 deletions src/dbus/qdbusconnection_p.h
Expand Up @@ -375,6 +375,25 @@ extern QDBusMessage qDBusPropertySet(const QDBusConnectionPrivate::ObjectTreeNod
const QDBusMessage &msg);
extern QDBusMessage qDBusPropertyGetAll(const QDBusConnectionPrivate::ObjectTreeNode &node,
const QDBusMessage &msg);

// can be replaced with a lambda in Qt 5.7
class QDBusConnectionDispatchEnabler : public QObject
{
Q_OBJECT
QDBusConnectionPrivate *con;
public:
QDBusConnectionDispatchEnabler(QDBusConnectionPrivate *con) : con(con) {}

public slots:
void execute()
{
con->setDispatchEnabled(true);
if (!con->ref.deref())
con->deleteLater();
deleteLater();
}
};

#endif // QT_BOOTSTRAPPED

QT_END_NAMESPACE
Expand Down
12 changes: 12 additions & 0 deletions src/dbus/qdbusintegrator.cpp
Expand Up @@ -310,9 +310,21 @@ static void qDBusNewConnection(DBusServer *server, DBusConnection *connection, v
// setPeer does the error handling for us
QDBusErrorInternal error;
newConnection->setPeer(connection, error);
newConnection->setDispatchEnabled(false);

// this is a queued connection and will resume in the QDBusServer's thread
emit serverConnection->newServerConnection(newConnection);

// we've disabled dispatching of events, so now we post an event to the
// QDBusServer's thread in order to enable it after the
// QDBusServer::newConnection() signal has been received by the
// application's code
newConnection->ref.ref();
QReadLocker serverLock(&serverConnection->lock);
QDBusConnectionDispatchEnabler *o = new QDBusConnectionDispatchEnabler(newConnection);
QTimer::singleShot(0, o, SLOT(execute()));
if (serverConnection->serverObject)
o->moveToThread(serverConnection->serverObject->thread());
}

void QDBusConnectionPrivate::_q_newConnection(QDBusConnectionPrivate *newConnection)
Expand Down
2 changes: 2 additions & 0 deletions src/dbus/qdbusserver.cpp
Expand Up @@ -97,13 +97,15 @@ QDBusServer::QDBusServer(QObject *parent)
*/
QDBusServer::~QDBusServer()
{
QWriteLocker locker(&d->lock);
if (QDBusConnectionManager::instance()) {
QMutexLocker locker(&QDBusConnectionManager::instance()->mutex);
Q_FOREACH (const QString &name, d->serverConnectionNames) {
QDBusConnectionManager::instance()->removeConnection(name);
}
d->serverConnectionNames.clear();
}
d->serverObject = nullptr;
d->ref.store(0);
d->deleteLater();
}
Expand Down

0 comments on commit d419f77

Please sign in to comment.