commit 28d887e5ab53bcef2877faa1c4bd1b93ce0230ae
parent 600e0fb902f88987e06c260b01ca426cb77ef382
Author: Martin Stransky <stransky@redhat.com>
Date: Fri, 14 Nov 2025 11:57:50 +0000
Bug 1996201 [Linux] Ref and check DBus connection r=emilio
Differential Revision: https://phabricator.services.mozilla.com/D269937
Diffstat:
3 files changed, 93 insertions(+), 0 deletions(-)
diff --git a/widget/gtk/GRefPtr.h b/widget/gtk/GRefPtr.h
@@ -54,6 +54,7 @@ GOBJECT_TRAITS(GdkWindow)
GOBJECT_TRAITS(GtkIconInfo)
GOBJECT_TRAITS(GIcon)
GOBJECT_TRAITS(::GSettings)
+GOBJECT_TRAITS(GDBusConnection)
#undef GOBJECT_TRAITS
diff --git a/widget/gtk/nsAppShell.cpp b/widget/gtk/nsAppShell.cpp
@@ -19,6 +19,7 @@
#include "mozilla/ProfilerLabels.h"
#include "mozilla/ProfilerThreadSleep.h"
#include "mozilla/GUniquePtr.h"
+#include "mozilla/GRefPtr.h"
#include "mozilla/StaticPrefs_widget.h"
#include "mozilla/WidgetUtils.h"
#include "nsIPowerManagerService.h"
@@ -277,6 +278,32 @@ void nsAppShell::DBusConnectClientResponse(GObject* aObject,
}
}
+void nsAppShell::DBusConnectionCheck() {
+ if (sAppShell && sAppShell->mDBusConnectionSession &&
+ sAppShell->mDBusConnectionSystem) {
+ MOZ_DIAGNOSTIC_ASSERT(
+ ((GObject*)sAppShell->mDBusConnectionSession.get())->ref_count > 1,
+ "Released mDBusConnectionSession connection?!");
+ MOZ_DIAGNOSTIC_ASSERT(
+ ((GObject*)sAppShell->mDBusConnectionSystem.get())->ref_count > 1,
+ "Released mDBusConnectionSystem connection?!");
+ }
+}
+
+void nsAppShell::SetSessionDBus(GDBusConnection* aDBusConnectionSession) {
+ if (sAppShell) {
+ sAppShell->mDBusConnectionSession = aDBusConnectionSession;
+ DBusConnectionCheck();
+ }
+}
+
+void nsAppShell::SetSystemDBus(GDBusConnection* aDBusConnectionSystem) {
+ if (sAppShell) {
+ sAppShell->mDBusConnectionSystem = aDBusConnectionSystem;
+ DBusConnectionCheck();
+ }
+}
+
// Based on
// https://github.com/lcp/NetworkManager/blob/240f47c892b4e935a3e92fc09eb15163d1fa28d8/src/nm-sleep-monitor-systemd.c
// Use login1 to signal sleep and wake notifications.
@@ -300,6 +327,52 @@ void nsAppShell::StartDBusListening() {
"org.freedesktop.timedate1", "/org/freedesktop/timedate1",
"org.freedesktop.DBus.Properties", mTimedate1ProxyCancellable,
reinterpret_cast<GAsyncReadyCallback>(DBusConnectClientResponse), this);
+
+ // Don't grab reference to DBus connect from xpcshell, it fails
+ // to release nsAppShell singleton and causes test timeout.
+ if (!g_getenv("XPCSHELL_TEST")) {
+ // Obtain session DBus connection
+ mDBusGetCancellableSession = dont_AddRef(g_cancellable_new());
+ g_bus_get(
+ G_BUS_TYPE_SESSION, mDBusGetCancellableSession,
+ [](GObject* aSourceObject, GAsyncResult* aRes, gpointer aUserData) {
+ GUniquePtr<GError> error;
+ GDBusConnection* conn =
+ g_bus_get_finish(aRes, getter_Transfers(error));
+ if (!conn) {
+ if (!IsCancelledGError(error.get())) {
+ NS_WARNING(
+ nsPrintfCString("Failure at g_bus_get_finish: %s",
+ error ? error->message : "Unknown Error")
+ .get());
+ }
+ return;
+ }
+ nsAppShell::SetSessionDBus(conn);
+ },
+ this);
+
+ // Obtain system-wide DBus connection
+ mDBusGetCancellableSystem = dont_AddRef(g_cancellable_new());
+ g_bus_get(
+ G_BUS_TYPE_SYSTEM, mDBusGetCancellableSystem,
+ [](GObject* aSourceObject, GAsyncResult* aRes, gpointer aUserData) {
+ GUniquePtr<GError> error;
+ GDBusConnection* conn =
+ g_bus_get_finish(aRes, getter_Transfers(error));
+ if (!conn) {
+ if (!IsCancelledGError(error.get())) {
+ NS_WARNING(
+ nsPrintfCString("Failure at g_bus_get_finish: %s",
+ error ? error->message : "Unknown Error")
+ .get());
+ }
+ return;
+ }
+ nsAppShell::SetSystemDBus(conn);
+ },
+ this);
+ }
}
void nsAppShell::StopDBusListening() {
@@ -322,6 +395,18 @@ void nsAppShell::StopDBusListening() {
mTimedate1ProxyCancellable = nullptr;
}
mTimedate1Proxy = nullptr;
+
+ DBusConnectionCheck();
+ if (mDBusGetCancellableSession) {
+ g_cancellable_cancel(mDBusGetCancellableSession);
+ mDBusGetCancellableSession = nullptr;
+ }
+ if (mDBusGetCancellableSystem) {
+ g_cancellable_cancel(mDBusGetCancellableSystem);
+ mDBusGetCancellableSystem = nullptr;
+ }
+ mDBusConnectionSession = nullptr;
+ mDBusConnectionSystem = nullptr;
}
#endif
diff --git a/widget/gtk/nsAppShell.h b/widget/gtk/nsAppShell.h
@@ -43,6 +43,9 @@ class nsAppShell : public nsBaseAppShell {
gpointer aUserData);
static void DBusConnectClientResponse(GObject* aObject, GAsyncResult* aResult,
gpointer aUserData);
+ static void DBusConnectionCheck();
+ static void SetSessionDBus(GDBusConnection* aDBusConnectionSession);
+ static void SetSystemDBus(GDBusConnection* aDBusConnectionSystem);
#endif
static void InstallTermSignalHandler();
@@ -64,6 +67,10 @@ class nsAppShell : public nsBaseAppShell {
RefPtr<GCancellable> mLogin1ProxyCancellable;
RefPtr<GDBusProxy> mTimedate1Proxy;
RefPtr<GCancellable> mTimedate1ProxyCancellable;
+ RefPtr<GDBusConnection> mDBusConnectionSession;
+ RefPtr<GDBusConnection> mDBusConnectionSystem;
+ RefPtr<GCancellable> mDBusGetCancellableSession;
+ RefPtr<GCancellable> mDBusGetCancellableSystem;
#endif
};