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>
diff --git a/libweston/compositor.c b/libweston/compositor.c
index 747c55f..6a300e0 100644
--- a/libweston/compositor.c
+++ b/libweston/compositor.c
@@ -1022,6 +1022,45 @@
}
}
+static void
+notify_view_output_destroy(struct wl_listener *listener, void *data)
+{
+ struct weston_view *view =
+ container_of(listener,
+ struct weston_view, output_destroy_listener);
+
+ view->output = NULL;
+ view->output_destroy_listener.notify = NULL;
+}
+
+/** Set the primary output of the view
+ *
+ * \param view The view whose primary output to set
+ * \param output The new primary output for the view
+ *
+ * Set \a output to be the primary output of the \a view.
+ *
+ * Notice that the assignment may be temporary; the primary output could be
+ * automatically changed. Hence, one cannot rely on the value persisting.
+ *
+ * Passing NULL as /a output will set the primary output to NULL.
+ */
+WL_EXPORT void
+weston_view_set_output(struct weston_view *view, struct weston_output *output)
+{
+ if (view->output_destroy_listener.notify) {
+ wl_list_remove(&view->output_destroy_listener.link);
+ view->output_destroy_listener.notify = NULL;
+ }
+ view->output = output;
+ if (output) {
+ view->output_destroy_listener.notify =
+ notify_view_output_destroy;
+ wl_signal_add(&output->destroy_signal,
+ &view->output_destroy_listener);
+ }
+}
+
/** Recalculate which output(s) the surface has views displayed on
*
* \param es The surface to remap to outputs
@@ -1113,7 +1152,7 @@
}
pixman_region32_fini(®ion);
- ev->output = new_output;
+ weston_view_set_output(ev, new_output);
ev->output_mask = mask;
weston_surface_assign_output(ev->surface);
@@ -1823,7 +1862,7 @@
return;
weston_view_damage_below(view);
- view->output = NULL;
+ weston_view_set_output(view, NULL);
view->plane = NULL;
view->is_mapped = false;
weston_layer_entry_remove(&view->layer_link);