libweston: add weston_view_set_output()

Instead of desktop shell assigning view outputs directly,
use a new method, weston_view_set_output(). The method can
set up an output destroy listener to make sure that views
do not have stale output pointers.

Without this patch it is possible to end up in a scenario
where, e.g. configure_static_view() accesses memory that
has already been freed. The scenario can be provoked by
repeatedly plugging and unplugging a display. The faulty
memory accesses are reported by valgrind.

Signed-off-by: Semi Malinen <semi.malinen@ge.com>
Signed-off-by: Fabien Lahoudere <fabien.lahoudere@collabora.com>
Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
This commit is contained in:
Semi Malinen
2018-04-26 11:08:10 +02:00
committed by Pekka Paalanen
parent 03dc95a131
commit e7a52fbb7d
3 changed files with 52 additions and 6 deletions
+7 -4
View File
@@ -580,7 +580,7 @@ create_focus_surface(struct weston_compositor *ec,
free(fsurf);
return NULL;
}
fsurf->view->output = output;
weston_view_set_output(fsurf->view, output);
fsurf->view->is_mapped = true;
weston_surface_set_size(surface, output->width, output->height);
@@ -2464,7 +2464,7 @@ map(struct desktop_shell *shell, struct shell_surface *shsurf,
shsurf->view->is_mapped = true;
if (shsurf->state.maximized) {
surface->output = shsurf->output;
shsurf->view->output = shsurf->output;
weston_view_set_output(shsurf->view, shsurf->output);
}
if (!shell->locked) {
@@ -2881,6 +2881,9 @@ configure_static_view(struct weston_view *ev, struct weston_layer *layer, int x,
{
struct weston_view *v, *next;
if (!ev->output)
return;
wl_list_for_each_safe(v, next, &layer->view_list.link, layer_link.link) {
if (v->output == ev->output && v != ev) {
weston_view_unmap(v);
@@ -2970,7 +2973,7 @@ desktop_shell_set_background(struct wl_client *client,
surface->committed_private = shell;
weston_surface_set_label_func(surface, background_get_label);
surface->output = weston_head_from_resource(output_resource)->output;
view->output = surface->output;
weston_view_set_output(view, surface->output);
sh_output = find_shell_output_from_weston_output(shell, surface->output);
if (sh_output->background_surface) {
@@ -3067,7 +3070,7 @@ desktop_shell_set_panel(struct wl_client *client,
surface->committed_private = shell;
weston_surface_set_label_func(surface, panel_get_label);
surface->output = weston_head_from_resource(output_resource)->output;
view->output = surface->output;
weston_view_set_output(view, surface->output);
sh_output = find_shell_output_from_weston_output(shell, surface->output);
if (sh_output->panel_surface) {