[PATCH weston] compositor: fix usage of dangling output pointer after destroying it
Giulio Camuffo
giuliocamuffo at gmail.com
Thu Jan 22 06:52:01 PST 2015
When an output is destroyed a view may still hold a pointer to it.
Calling weston_view_assign_output() on one view of a surface ends up
updating the output on that view and later iterating over all the views
of a surface and using their output, which may be bogus.
Instead, call weston_surface_assign_output(), and update the output
of all the views.
---
src/compositor.c | 53 ++++++++++++++++++++++++++---------------------------
1 file changed, 26 insertions(+), 27 deletions(-)
diff --git a/src/compositor.c b/src/compositor.c
index 821970a..651c37a 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -799,10 +799,10 @@ weston_surface_update_output_mask(struct weston_surface *es, uint32_t mask)
static void
-weston_surface_assign_output(struct weston_surface *es)
+weston_view_assign_output(struct weston_view *ev)
{
- struct weston_output *new_output;
- struct weston_view *view;
+ struct weston_compositor *ec = ev->surface->compositor;
+ struct weston_output *output, *new_output;
pixman_region32_t region;
uint32_t max, area, mask;
pixman_box32_t *e;
@@ -811,34 +811,32 @@ weston_surface_assign_output(struct weston_surface *es)
max = 0;
mask = 0;
pixman_region32_init(®ion);
- wl_list_for_each(view, &es->views, surface_link) {
- if (!view->output)
- continue;
-
- pixman_region32_intersect(®ion, &view->transform.boundingbox,
- &view->output->region);
+ wl_list_for_each(output, &ec->output_list, link) {
+ pixman_region32_intersect(®ion, &ev->transform.boundingbox,
+ &output->region);
e = pixman_region32_extents(®ion);
area = (e->x2 - e->x1) * (e->y2 - e->y1);
- mask |= view->output_mask;
+ if (area > 0)
+ mask |= 1 << output->id;
if (area >= max) {
- new_output = view->output;
+ new_output = output;
max = area;
}
}
pixman_region32_fini(®ion);
- es->output = new_output;
- weston_surface_update_output_mask(es, mask);
+ ev->output = new_output;
+ ev->output_mask = mask;
}
static void
-weston_view_assign_output(struct weston_view *ev)
+weston_surface_assign_output(struct weston_surface *es)
{
- struct weston_compositor *ec = ev->surface->compositor;
- struct weston_output *output, *new_output;
+ struct weston_output *new_output;
+ struct weston_view *view;
pixman_region32_t region;
uint32_t max, area, mask;
pixman_box32_t *e;
@@ -847,27 +845,28 @@ weston_view_assign_output(struct weston_view *ev)
max = 0;
mask = 0;
pixman_region32_init(®ion);
- wl_list_for_each(output, &ec->output_list, link) {
- pixman_region32_intersect(®ion, &ev->transform.boundingbox,
- &output->region);
+ wl_list_for_each(view, &es->views, surface_link) {
+ weston_view_assign_output(view);
+ if (!view->output)
+ continue;
+
+ pixman_region32_intersect(®ion, &view->transform.boundingbox,
+ &view->output->region);
e = pixman_region32_extents(®ion);
area = (e->x2 - e->x1) * (e->y2 - e->y1);
- if (area > 0)
- mask |= 1 << output->id;
+ mask |= view->output_mask;
if (area >= max) {
- new_output = output;
+ new_output = view->output;
max = area;
}
}
pixman_region32_fini(®ion);
- ev->output = new_output;
- ev->output_mask = mask;
-
- weston_surface_assign_output(ev->surface);
+ es->output = new_output;
+ weston_surface_update_output_mask(es, mask);
}
static void
@@ -1035,7 +1034,7 @@ weston_view_update_transform(struct weston_view *view)
weston_view_damage_below(view);
- weston_view_assign_output(view);
+ weston_surface_assign_output(view->surface);
wl_signal_emit(&view->surface->compositor->transform_signal,
view->surface);
--
2.2.2
More information about the wayland-devel
mailing list