perf-tool: Spawn perf-tool-helper from gnome-shell

On Wayland, the display server is the Wayland compositor, i.e.
`gnome-shell` itself.

As a result, we cannot spawn `gnome-shell-perf-helper` before
`gnome-shell` is started, as `gnome-shell-perf-helper` needs to connect
to the display server.

So, instead of spawning `gnome-shell-perf-helper` from the perf tool,
start it from `gnome-shell` itself.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/941
This commit is contained in:
Olivier Fourdan 2020-01-24 10:59:31 +01:00 committed by Florian Müllner
parent a750d04bdb
commit ee7e62c9c8
2 changed files with 34 additions and 70 deletions

View File

@ -5,8 +5,10 @@
const { Gio, GLib, Meta, Shell } = imports.gi; const { Gio, GLib, Meta, Shell } = imports.gi;
const Config = imports.misc.config;
const Main = imports.ui.main; const Main = imports.ui.main;
const Params = imports.misc.params; const Params = imports.misc.params;
const Util = imports.misc.util;
const { loadInterfaceXML } = imports.misc.fileUtils; const { loadInterfaceXML } = imports.misc.fileUtils;
@ -77,6 +79,12 @@ function _getPerfHelper() {
return _perfHelper; return _perfHelper;
} }
function _spawnPerfHelper() {
let path = Config.LIBEXECDIR;
let command = `${path}/gnome-shell-perf-helper`;
Util.trySpawnCommandLine(command);
}
function _callRemote(obj, method, ...args) { function _callRemote(obj, method, ...args) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
args.push((result, excp) => { args.push((result, excp) => {
@ -276,6 +284,25 @@ function _collect(scriptModule, outputFile) {
} }
} }
async function _runPerfScript(scriptModule, outputFile) {
for (let step of scriptModule.run()) {
try {
await step; // eslint-disable-line no-await-in-loop
} catch (err) {
log(`Script failed: ${err}\n${err.stack}`);
Meta.exit(Meta.ExitCode.ERROR);
}
}
try {
_collect(scriptModule, outputFile);
} catch (err) {
log(`Script failed: ${err}\n${err.stack}`);
Meta.exit(Meta.ExitCode.ERROR);
}
Meta.exit(Meta.ExitCode.SUCCESS);
}
/** /**
* runPerfScript * runPerfScript
* @param {Object} scriptModule: module object with run and finish * @param {Object} scriptModule: module object with run and finish
@ -317,23 +344,13 @@ function _collect(scriptModule, outputFile) {
* After running the script and collecting statistics from the * After running the script and collecting statistics from the
* event log, GNOME Shell will exit. * event log, GNOME Shell will exit.
**/ **/
async function runPerfScript(scriptModule, outputFile) { function runPerfScript(scriptModule, outputFile) {
Shell.PerfLog.get_default().set_enabled(true); Shell.PerfLog.get_default().set_enabled(true);
_spawnPerfHelper();
for (let step of scriptModule.run()) { Gio.bus_watch_name(Gio.BusType.SESSION,
try { 'org.gnome.Shell.PerfHelper',
await step; // eslint-disable-line no-await-in-loop Gio.BusNameWatcherFlags.NONE,
} catch (err) { () => _runPerfScript(scriptModule, outputFile),
log(`Script failed: ${err}\n${err.stack}`); null);
Meta.exit(Meta.ExitCode.ERROR);
}
}
try {
_collect(scriptModule, outputFile);
} catch (err) {
log(`Script failed: ${err}\n${err.stack}`);
Meta.exit(Meta.ExitCode.ERROR);
}
Meta.exit(Meta.ExitCode.SUCCESS);
} }

View File

@ -24,52 +24,6 @@ def show_version(option, opt_str, value, parser):
print("GNOME Shell Performance Test @VERSION@") print("GNOME Shell Performance Test @VERSION@")
sys.exit() sys.exit()
def wait_for_dbus_name(wait_name):
loop = GLib.MainLoop()
def on_name_appeared(connection, name, new_owner, *args):
if not (name == wait_name and new_owner != ''):
return
loop.quit()
return
watch_id = Gio.bus_watch_name(Gio.BusType.SESSION,
wait_name,
Gio.BusNameWatcherFlags.NONE,
on_name_appeared,
None)
def on_timeout():
print("\nFailed to start %s: timed out" % (wait_name,))
sys.exit(1)
GLib.timeout_add_seconds(7, on_timeout)
loop.run()
Gio.bus_unwatch_name(watch_id)
PERF_HELPER_NAME = "org.gnome.Shell.PerfHelper"
PERF_HELPER_IFACE = "org.gnome.Shell.PerfHelper"
PERF_HELPER_PATH = "/org/gnome/Shell/PerfHelper"
def start_perf_helper():
self_dir = os.path.dirname(os.path.abspath(sys.argv[0]))
perf_helper_path = "@libexecdir@/gnome-shell-perf-helper"
subprocess.Popen([perf_helper_path])
wait_for_dbus_name (PERF_HELPER_NAME)
def stop_perf_helper():
bus = Gio.bus_get_sync(Gio.BusType.SESSION, None)
proxy = Gio.DBusProxy.new_sync(bus,
Gio.DBusProxyFlags.NONE,
None,
PERF_HELPER_NAME,
PERF_HELPER_PATH,
PERF_HELPER_IFACE,
None)
proxy.Exit()
def start_shell(perf_output=None): def start_shell(perf_output=None):
# Set up environment # Set up environment
env = dict(os.environ) env = dict(os.environ)
@ -204,8 +158,6 @@ def run_performance_test():
logs = [] logs = []
metric_summaries = {} metric_summaries = {}
start_perf_helper()
for i in range(0, iters): for i in range(0, iters):
# We create an empty temporary file that the shell will overwrite # We create an empty temporary file that the shell will overwrite
# with the contents. # with the contents.
@ -217,14 +169,12 @@ def run_performance_test():
try: try:
normal_exit = run_shell(perf_output=output_file) normal_exit = run_shell(perf_output=output_file)
except: except:
stop_perf_helper()
raise raise
finally: finally:
if not normal_exit: if not normal_exit:
os.remove(output_file) os.remove(output_file)
if not normal_exit: if not normal_exit:
stop_perf_helper()
return False return False
try: try:
@ -232,7 +182,6 @@ def run_performance_test():
output = json.load(f) output = json.load(f)
f.close() f.close()
except: except:
stop_perf_helper()
raise raise
finally: finally:
os.remove(output_file) os.remove(output_file)
@ -260,8 +209,6 @@ def run_performance_test():
logs.append(output['log']) logs.append(output['log'])
stop_perf_helper()
if options.perf_output or options.perf_upload: if options.perf_output or options.perf_upload:
# Write a complete report, formatted as JSON. The Javascript/C code that # Write a complete report, formatted as JSON. The Javascript/C code that
# generates the individual reports we are summarizing here is very careful # generates the individual reports we are summarizing here is very careful