on xenial help sign in
Fix timing of DBus registrations to avoid a race
commitf4fcd19e9e548957266dd3fc19b00d0d2c7f4ab8 authorMichael Terry <michael.terry@canonical.com> dateWed 8 Oct 2014, 09:34 (12 years ago) parent48f22f3
12 files changed+73−34
plugins/LightDM/Greeter.cpp+21 plugins/LightDM/Greeter.h+1 plugins/LightDM/plugin.cpp+1−15 plugins/Unity/DashCommunicator/dbusdashcommunicatorservice.cpp+11−4 plugins/Unity/DashCommunicator/dbusdashcommunicatorservice.h+2 plugins/Unity/Launcher/dbusinterface.cpp+15−8 plugins/Unity/Launcher/dbusinterface.h+2 plugins/Unity/Session/dbusunitysessionservice.cpp+14−7 plugins/Unity/Session/dbusunitysessionservice.h+2 tests/plugins/LightDM/CMakeLists.txt+2 tests/plugins/Unity/Launcher/launchermodeltest.cpp+1 tests/plugins/Unity/Session/sessionbackendtest.cpp+1
plugins/LightDM/Greeter.cpp+21
@@ -16,9 +16,17 @@
1616 * Author: Michael Terry <michael.terry@canonical.com>
1717 */
1818
19+#include "DBusGreeter.h"
20+#include "DBusGreeterList.h"
1921#include "Greeter.h"
2022#include <libintl.h>
2123#include <QLightDM/Greeter>
24+#include <QTimer>
25+
26+static const char* GREETER_DBUS_PATH = "/";
27+static const char* GREETER_LIST_DBUS_PATH = "/list";
28+static const char* GREETER_DBUS_SERVICE = "com.canonical.UnityGreeter";
29+
2230
2331class GreeterPrivate
2432{
@@ -61,6 +69,9 @@ Greeter::Greeter(QObject* parent)
6169 this, SLOT(authenticationCompleteFilter()));
6270
6371 d->m_greeter->connectSync();
72+
73+ // Use a zero-timer to let Qml finish loading before we announce on DBus
74+ QTimer::singleShot(0, this, SLOT(registerDBus()));
6475}
6576
6677bool Greeter::isActive() const
@@ -154,3 +165,13 @@ void Greeter::authenticationCompleteFilter()
154165 Q_EMIT isAuthenticatedChanged();
155166 Q_EMIT authenticationComplete();
156167}
168+
169+void Greeter::registerDBus()
170+{
171+ QDBusConnection connection = QDBusConnection::sessionBus();
172+ DBusGreeter *root = new DBusGreeter(this, connection, GREETER_DBUS_PATH);
173+ connection.registerObject(GREETER_DBUS_PATH, root, QDBusConnection::ExportScriptableContents);
174+ DBusGreeterList *list = new DBusGreeterList(this, connection, GREETER_LIST_DBUS_PATH);
175+ connection.registerObject(GREETER_LIST_DBUS_PATH, list, QDBusConnection::ExportScriptableContents);
176+ connection.registerService(GREETER_DBUS_SERVICE);
177+}
plugins/LightDM/Greeter.h+1
@@ -77,6 +77,7 @@ private Q_SLOTS:
7777 void showMessageFilter(const QString &text, QLightDM::Greeter::MessageType type);
7878 void showPromptFilter(const QString &text, QLightDM::Greeter::PromptType type);
7979 void authenticationCompleteFilter();
80+ void registerDBus();
8081};
8182
8283#endif
plugins/LightDM/plugin.cpp+1−15
@@ -18,8 +18,6 @@
1818 */
1919
2020#include "plugin.h"
21−#include "DBusGreeter.h"
22−#include "DBusGreeterList.h"
2321#include "Greeter.h"
2422#include "UsersModel.h"
2523#include <libusermetricsoutput/ColorTheme.h>
@@ -30,23 +28,11 @@
3028#include <QDBusConnection>
3129#include <QtQml/qqml.h>
3230
33−static const char* GREETER_LIST_DBUS_PATH = "/list";
34−static const char* GREETER_DBUS_SERVICE = "com.canonical.UnityGreeter";
35−
3631static QObject *greeter_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
3732{
3833 Q_UNUSED(engine)
3934 Q_UNUSED(scriptEngine)
40−
41− Greeter *greeter = new Greeter();
42− QDBusConnection connection = QDBusConnection::sessionBus();
43− DBusGreeter *root = new DBusGreeter(greeter, connection, "/");
44− connection.registerObject("/", root, QDBusConnection::ExportScriptableContents);
45− DBusGreeterList *list = new DBusGreeterList(greeter, connection, GREETER_LIST_DBUS_PATH);
46− connection.registerObject(GREETER_LIST_DBUS_PATH, list, QDBusConnection::ExportScriptableContents);
47− connection.registerService(GREETER_DBUS_SERVICE);
48−
49− return greeter;
35+ return new Greeter();
5036}
5137
5238static QObject *users_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
plugins/Unity/DashCommunicator/dbusdashcommunicatorservice.cpp+11−4
@@ -19,14 +19,13 @@
1919#include <QDBusConnection>
2020#include <QDBusInterface>
2121#include <QDebug>
22+#include <QTimer>
2223
2324DBusDashCommunicatorService::DBusDashCommunicatorService(QObject *parent):
2425 QObject(parent)
2526{
26− QDBusConnection connection = QDBusConnection::sessionBus();
27−
28− connection.registerService("com.canonical.UnityDash");
29− connection.registerObject("/com/canonical/UnityDash", this, QDBusConnection::ExportScriptableSlots);
27+ // Use a zero-timer to let Qml finish loading before we announce on DBus
28+ QTimer::singleShot(0, this, SLOT(registerDBus()));
3029}
3130
3231DBusDashCommunicatorService::~DBusDashCommunicatorService()
@@ -37,3 +36,11 @@ void DBusDashCommunicatorService::SetCurrentScope(const QString &scopeId, bool a
3736{
3837 Q_EMIT setCurrentScopeRequested(scopeId, animate, isSwipe);
3938}
39+
40+void DBusDashCommunicatorService::registerDBus()
41+{
42+ QDBusConnection connection = QDBusConnection::sessionBus();
43+
44+ connection.registerService("com.canonical.UnityDash");
45+ connection.registerObject("/com/canonical/UnityDash", this, QDBusConnection::ExportScriptableSlots);
46+}
plugins/Unity/DashCommunicator/dbusdashcommunicatorservice.h+2
@@ -34,6 +34,8 @@ Q_SIGNALS:
3434public Q_SLOTS:
3535 Q_SCRIPTABLE void SetCurrentScope(const QString &scopeId, bool animate, bool isSwipe);
3636
37+private Q_SLOTS:
38+ void registerDBus();
3739};
3840
3941#endif // DBUSUNITYSESSIONSERVICE_H
plugins/Unity/Launcher/dbusinterface.cpp+15−8
@@ -25,19 +25,14 @@
2525#include <QDBusConnection>
2626#include <QDBusMessage>
2727#include <QDebug>
28+#include <QTimer>
2829
2930DBusInterface::DBusInterface(LauncherModel *parent):
3031 QDBusVirtualObject(parent),
3132 m_launcherModel(parent)
3233{
33− /* Set up ourselves on DBus */
34− QDBusConnection con = QDBusConnection::sessionBus();
35− if (!con.registerService("com.canonical.Unity.Launcher")) {
36− qWarning() << "Unable to register launcher name";
37− }
38− if (!con.registerVirtualObject("/com/canonical/Unity/Launcher", this, QDBusConnection::VirtualObjectRegisterOption::SubPath)) {
39− qWarning() << "Unable to register launcher object";
40− }
34+ // Use a zero-timer to let Qml finish loading before we announce on DBus
35+ QTimer::singleShot(0, this, SLOT(registerDBus()));
4136}
4237
4338DBusInterface::~DBusInterface()
@@ -230,3 +225,15 @@ void DBusInterface::emitPropChangedDbus(const QString& appId, const QString& pro
230225 QDBusConnection con = QDBusConnection::sessionBus();
231226 con.send(message);
232227}
228+
229+void DBusInterface::registerDBus()
230+{
231+ /* Set up ourselves on DBus */
232+ QDBusConnection con = QDBusConnection::sessionBus();
233+ if (!con.registerService("com.canonical.Unity.Launcher")) {
234+ qWarning() << "Unable to register launcher name";
235+ }
236+ if (!con.registerVirtualObject("/com/canonical/Unity/Launcher", this, QDBusConnection::VirtualObjectRegisterOption::SubPath)) {
237+ qWarning() << "Unable to register launcher object";
238+ }
239+}
plugins/Unity/Launcher/dbusinterface.h+2
@@ -47,4 +47,6 @@ private:
4747
4848 LauncherModel *m_launcherModel;
4949
50+private Q_SLOTS:
51+ void registerDBus();
5052};
plugins/Unity/Session/dbusunitysessionservice.cpp+14−7
@@ -20,16 +20,12 @@
2020// Qt
2121#include <QDBusConnection>
2222#include <QDBusInterface>
23+#include <QTimer>
2324
2425DBusUnitySessionService::DBusUnitySessionService() : QObject()
2526{
26− QDBusConnection connection = QDBusConnection::sessionBus();
27−
28− connection.registerService("com.canonical.Unity");
29− connection.registerObject("/com/canonical/Unity/Session", this,
30− QDBusConnection::ExportScriptableSignals
31− | QDBusConnection::ExportScriptableSlots
32− | QDBusConnection::ExportScriptableInvokables);
27+ // Use a zero-timer to let Qml finish loading before we announce on DBus
28+ QTimer::singleShot(0, this, SLOT(registerDBus()));
3329}
3430
3531DBusUnitySessionService::~DBusUnitySessionService()
@@ -77,3 +73,14 @@ void DBusUnitySessionService::RequestShutdown()
7773{
7874 Q_EMIT shutdownRequested(false);
7975}
76+
77+void DBusUnitySessionService::registerDBus()
78+{
79+ QDBusConnection connection = QDBusConnection::sessionBus();
80+
81+ connection.registerService("com.canonical.Unity");
82+ connection.registerObject("/com/canonical/Unity/Session", this,
83+ QDBusConnection::ExportScriptableSignals
84+ | QDBusConnection::ExportScriptableSlots
85+ | QDBusConnection::ExportScriptableInvokables);
86+}
plugins/Unity/Session/dbusunitysessionservice.h+2
@@ -134,6 +134,8 @@ public Q_SLOTS:
134134 */
135135 Q_SCRIPTABLE void RequestShutdown();
136136
137+private Q_SLOTS:
138+ void registerDBus();
137139};
138140
139141#endif // DBUSUNITYSESSIONSERVICE_H
tests/plugins/LightDM/CMakeLists.txt+2
@@ -1,5 +1,7 @@
11add_executable(test-lightdm-dbus
22 dbus.cpp
3+ ${CMAKE_SOURCE_DIR}/plugins/LightDM/DBusGreeter.cpp
4+ ${CMAKE_SOURCE_DIR}/plugins/LightDM/DBusGreeterList.cpp
35 ${CMAKE_SOURCE_DIR}/plugins/LightDM/Greeter.cpp
46 )
57qt5_use_modules(test-lightdm-dbus Core DBus Quick Test)
tests/plugins/Unity/Launcher/launchermodeltest.cpp+1
@@ -124,6 +124,7 @@ private Q_SLOTS:
124124
125125 void initTestCase() {
126126 launcherModel = new LauncherModel(this);
127+ QCoreApplication::processEvents(); // to let the model register on DBus
127128 QCOMPARE(launcherModel->rowCount(QModelIndex()), 0);
128129
129130 appManager = new MockAppManager(this);
tests/plugins/Unity/Session/sessionbackendtest.cpp+1
@@ -45,6 +45,7 @@ private Q_SLOTS:
4545 QFETCH(QString, method);
4646
4747 DBusUnitySessionService dbusUnitySessionService;
48+ QCoreApplication::processEvents(); // to let the service register on DBus
4849
4950 QDBusConnection con = QDBusConnection::sessionBus();
5051 QDBusInterface interface ("com.canonical.Unity",