QDBusServer: delay processing of D-Bus messages
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>
This commit is contained in:
parent
43a710df63
commit
a32217cb55
@ -68,24 +68,6 @@ static void preventDllUnload();
|
|||||||
|
|
||||||
Q_GLOBAL_STATIC(QDBusConnectionManager, _q_manager)
|
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
|
struct QDBusConnectionManager::ConnectionRequestData
|
||||||
{
|
{
|
||||||
enum RequestType {
|
enum RequestType {
|
||||||
@ -1281,8 +1263,6 @@ QByteArray QDBusConnection::localMachineId()
|
|||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#include "qdbusconnection.moc"
|
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
# include <qt_windows.h>
|
# include <qt_windows.h>
|
||||||
|
|
||||||
|
@ -375,6 +375,25 @@ extern QDBusMessage qDBusPropertySet(const QDBusConnectionPrivate::ObjectTreeNod
|
|||||||
const QDBusMessage &msg);
|
const QDBusMessage &msg);
|
||||||
extern QDBusMessage qDBusPropertyGetAll(const QDBusConnectionPrivate::ObjectTreeNode &node,
|
extern QDBusMessage qDBusPropertyGetAll(const QDBusConnectionPrivate::ObjectTreeNode &node,
|
||||||
const QDBusMessage &msg);
|
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
|
#endif // QT_BOOTSTRAPPED
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -309,9 +309,21 @@ static void qDBusNewConnection(DBusServer *server, DBusConnection *connection, v
|
|||||||
// setPeer does the error handling for us
|
// setPeer does the error handling for us
|
||||||
QDBusErrorInternal error;
|
QDBusErrorInternal error;
|
||||||
newConnection->setPeer(connection, error);
|
newConnection->setPeer(connection, error);
|
||||||
|
newConnection->setDispatchEnabled(false);
|
||||||
|
|
||||||
// this is a queued connection and will resume in the QDBusServer's thread
|
// this is a queued connection and will resume in the QDBusServer's thread
|
||||||
emit serverConnection->newServerConnection(newConnection);
|
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)
|
void QDBusConnectionPrivate::_q_newConnection(QDBusConnectionPrivate *newConnection)
|
||||||
|
@ -97,6 +97,7 @@ QDBusServer::QDBusServer(QObject *parent)
|
|||||||
*/
|
*/
|
||||||
QDBusServer::~QDBusServer()
|
QDBusServer::~QDBusServer()
|
||||||
{
|
{
|
||||||
|
QWriteLocker locker(&d->lock);
|
||||||
if (QDBusConnectionManager::instance()) {
|
if (QDBusConnectionManager::instance()) {
|
||||||
QMutexLocker locker(&QDBusConnectionManager::instance()->mutex);
|
QMutexLocker locker(&QDBusConnectionManager::instance()->mutex);
|
||||||
Q_FOREACH (const QString &name, d->serverConnectionNames) {
|
Q_FOREACH (const QString &name, d->serverConnectionNames) {
|
||||||
@ -104,6 +105,7 @@ QDBusServer::~QDBusServer()
|
|||||||
}
|
}
|
||||||
d->serverConnectionNames.clear();
|
d->serverConnectionNames.clear();
|
||||||
}
|
}
|
||||||
|
d->serverObject = nullptr;
|
||||||
d->ref.store(0);
|
d->ref.store(0);
|
||||||
d->deleteLater();
|
d->deleteLater();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user