Use weston_compositor_add_destroy_listener_once() in plugins

This introduces a new convention of checking through the compositor destroy
listener if the plugin is already initialized. If the plugin is already
initialized, then the plugin entry function succeeds as a no-op. This makes it
safe to load the same plugin multiple times in a running compositor.

Currently module loading functions return failure if a plugin is already
loaded, but that will change in the future. Therefore we need this other method
of ensuring we do not double-initialize a plugin which would lead to list
corruptions the very least.

All plugins are converted to use the new helper, except:
- those that do not have a destroy listener already, and
- hmi-controller which does the same open-coded as the common code pattern
  did not fit there.

Plugins should always have a compositor destroy listener registered since they
very least allocate a struct to hold their data. Hence omissions are
highlighted in code.

Backends do not need this because weston_compositor_load_backend() already
protects against double-init. GL-renderer does not export a standard module
init function so cannot be initialized the usual way and therefore is not
vulnerable to double-init.

Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
This commit is contained in:
Pekka Paalanen
2019-11-06 12:59:32 +02:00
committed by Daniel Stone
parent 5caef6d355
commit 6ffbba3ac1
15 changed files with 125 additions and 30 deletions
+15 -9
View File
@@ -367,19 +367,24 @@ weston_module_init(struct weston_compositor *compositor)
wxs->wl_display = display;
wxs->compositor = compositor;
if (!weston_compositor_add_destroy_listener_once(compositor,
&wxs->destroy_listener,
weston_xserver_destroy)) {
free(wxs);
return 0;
}
if (weston_xwayland_get_api(compositor) != NULL ||
weston_xwayland_surface_get_api(compositor) != NULL) {
weston_log("The xwayland module APIs are already loaded.\n");
free(wxs);
return -1;
goto out_free;
}
ret = weston_plugin_api_register(compositor, WESTON_XWAYLAND_API_NAME,
&api, sizeof(api));
if (ret < 0) {
weston_log("Failed to register the xwayland module API.\n");
free(wxs);
return -1;
goto out_free;
}
ret = weston_plugin_api_register(compositor,
@@ -387,13 +392,9 @@ weston_module_init(struct weston_compositor *compositor)
&surface_api, sizeof(surface_api));
if (ret < 0) {
weston_log("Failed to register the xwayland surface API.\n");
free(wxs);
return -1;
goto out_free;
}
wxs->destroy_listener.notify = weston_xserver_destroy;
wl_signal_add(&compositor->destroy_signal, &wxs->destroy_listener);
wxs->wm_debug =
weston_compositor_add_log_scope(wxs->compositor->weston_log_ctx,
"xwm-wm-x11",
@@ -401,4 +402,9 @@ weston_module_init(struct weston_compositor *compositor)
NULL, NULL, NULL);
return 0;
out_free:
wl_list_remove(&wxs->destroy_listener.link);
free(wxs);
return -1;
}