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:
parent
97b7dee564
commit
4880364cd2
@ -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() {
|
||||||
|
Loading…
Reference in New Issue
Block a user