objectManager: Simplify fetching of remote objects

Instead of maintaining an inhibitor count, fetch objects and
their interfaces asynchronously and wait for all promises to
settle.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2344>
This commit is contained in:
Florian Müllner 2022-07-08 08:52:18 +02:00 committed by Marge Bot
parent 97b7dee564
commit 4880364cd2

View File

@ -61,31 +61,19 @@ var ObjectManager = class extends Signals.EventEmitter {
if (params.knownInterfaces) if (params.knownInterfaces)
this._registerInterfaces(params.knownInterfaces); this._registerInterfaces(params.knownInterfaces);
// Start out inhibiting load until at least the proxy
// manager is loaded and the remote objects are fetched
this._numLoadInhibitors = 1;
this._initManagerProxy(); this._initManagerProxy();
} }
_tryToCompleteLoad() { _completeLoad() {
if (this._numLoadInhibitors === 0) if (this._onLoaded)
return; this._onLoaded();
this._numLoadInhibitors--;
if (this._numLoadInhibitors === 0) {
if (this._onLoaded)
this._onLoaded();
}
} }
async _addInterface(objectPath, interfaceName, onFinished) { async _addInterface(objectPath, interfaceName) {
let info = this._interfaceInfos[interfaceName]; let info = this._interfaceInfos[interfaceName];
if (!info) { if (!info)
if (onFinished)
onFinished();
return; return;
}
const proxy = new Gio.DBusProxy({ const proxy = new Gio.DBusProxy({
g_connection: this._connection, g_connection: this._connection,
@ -100,9 +88,6 @@ var ObjectManager = class extends Signals.EventEmitter {
await proxy.init_async(GLib.PRIORITY_DEFAULT, this._cancellable); await proxy.init_async(GLib.PRIORITY_DEFAULT, this._cancellable);
} catch (e) { } catch (e) {
logError(e, `could not initialize proxy for interface ${interfaceName}`); logError(e, `could not initialize proxy for interface ${interfaceName}`);
if (onFinished)
onFinished();
return; return;
} }
@ -125,9 +110,6 @@ var ObjectManager = class extends Signals.EventEmitter {
this.emit('object-added', objectPath); this.emit('object-added', objectPath);
this.emit('interface-added', interfaceName, proxy); this.emit('interface-added', interfaceName, proxy);
if (onFinished)
onFinished();
} }
_removeInterface(objectPath, interfaceName) { _removeInterface(objectPath, interfaceName) {
@ -163,7 +145,7 @@ var ObjectManager = class extends Signals.EventEmitter {
} catch (e) { } catch (e) {
logError(e, `could not initialize object manager for object ${this._serviceName}`); logError(e, `could not initialize object manager for object ${this._serviceName}`);
this._tryToCompleteLoad(); this._completeLoad();
return; return;
} }
@ -180,7 +162,7 @@ var ObjectManager = class extends Signals.EventEmitter {
}); });
if (Object.keys(this._interfaceInfos).length === 0) { if (Object.keys(this._interfaceInfos).length === 0) {
this._tryToCompleteLoad(); this._completeLoad();
return; return;
} }
@ -195,40 +177,27 @@ var ObjectManager = class extends Signals.EventEmitter {
this._onNameAppeared(); this._onNameAppeared();
} }
_onNameAppeared() { async _onNameAppeared() {
this._managerProxy.GetManagedObjectsRemote((result, error) => { try {
if (!result) { const [objects] = await this._managerProxy.GetManagedObjectsAsync();
if (error)
logError(error, `could not get remote objects for service ${this._serviceName} path ${this._managerPath}`);
this._tryToCompleteLoad();
return;
}
let [objects] = result;
if (!objects) { if (!objects) {
this._tryToCompleteLoad(); this._completeLoad();
return; return;
} }
let objectPaths = Object.keys(objects); const objectPaths = Object.keys(objects);
for (let i = 0; i < objectPaths.length; i++) { await Promise.allSettled(objectPaths.flatMap(objectPath => {
let objectPath = objectPaths[i]; const object = objects[objectPath];
let object = objects[objectPath]; const interfaceNames = Object.getOwnPropertyNames(object);
return interfaceNames.map(
let interfaceNames = Object.getOwnPropertyNames(object); ifaceName => this._addInterface(objectPath, ifaceName));
for (let j = 0; j < interfaceNames.length; j++) { }));
let interfaceName = interfaceNames[j]; } catch (error) {
logError(error, `could not get remote objects for service ${this._serviceName} path ${this._managerPath}`);
// Prevent load from completing until the interface is loaded } finally {
this._numLoadInhibitors++; this._completeLoad();
this._addInterface(objectPath, interfaceName, }
this._tryToCompleteLoad.bind(this));
}
}
this._tryToCompleteLoad();
});
} }
_onNameVanished() { _onNameVanished() {