From 2c91b6164c34e786c8063a5979b4ee04de7b0656 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Fri, 20 Mar 2020 22:32:08 +0100 Subject: [PATCH] dbusServices: Allow to inhibit auto-shutdown While we only shut down after a method call completed or (if the interface has signals) the sender disconnects from the bus, services may need to inhibit auto-shutdown for more specific reasons themselves, for example when a method call kicks off an operation that should complete before shutting down. Add hold() and release() methods like Gio.Application for those cases. https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1115 --- js/dbusServices/dbusService.js | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/js/dbusServices/dbusService.js b/js/dbusServices/dbusService.js index 21b8f9c4b..93873e287 100644 --- a/js/dbusServices/dbusService.js +++ b/js/dbusServices/dbusService.js @@ -18,6 +18,7 @@ var ServiceImplementation = class { this._injectTracking('return_value_with_unix_fd_list'); this._senders = new Map(); + this._holdCount = 0; this._hasSignals = this._dbusImpl.get_info().signals.length > 0; this._shutdownTimeoutId = 0; @@ -38,6 +39,22 @@ var ServiceImplementation = class { this._dbusImpl.unexport(); } + hold() { + this._holdCount++; + } + + release() { + if (this._holdCount === 0) { + logError(new Error('Unmatched call to release()')); + return; + } + + this._holdCount--; + + if (this._holdCount === 0) + this._queueShutdownCheck(); + } + /** * _handleError: * @param {Gio.DBusMethodInvocation} @@ -69,7 +86,7 @@ var ServiceImplementation = class { if (!this._autoShutdown) return; - if (this._senders.size > 0) + if (this._holdCount > 0) return; this.emit('shutdown'); @@ -93,6 +110,7 @@ var ServiceImplementation = class { if (this._senders.has(sender)) return; + this.hold(); this._senders.set(sender, this._dbusImpl.get_connection().watch_name( sender, @@ -108,7 +126,7 @@ var ServiceImplementation = class { this._dbusImpl.get_connection().unwatch_name(id); if (this._senders.delete(sender)) - this._queueShutdownCheck(); + this.release(); } _injectTracking(methodName) {