summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPekka Paalanen <pekka.paalanen@collabora.co.uk>2017-10-26 14:33:59 +0300
committerPekka Paalanen <pekka.paalanen@collabora.co.uk>2018-04-17 15:19:57 +0300
commitdcbcfc7f678d96d9c26514fa47d65d992bb5b48c (patch)
tree980669bc38112a425fcc0eb7c5f2cbc4887b52c4
parent586e1ac791e7a514b71db873b477b137f02aa0b4 (diff)
downloadweston-dcbcfc7f678d96d9c26514fa47d65d992bb5b48c.tar.gz
weston-dcbcfc7f678d96d9c26514fa47d65d992bb5b48c.tar.bz2
weston-dcbcfc7f678d96d9c26514fa47d65d992bb5b48c.zip
libweston: cancel idle_repaint on output destroy
If the idle_repaint() callback has been scheduled when a weston_output gets destroyed, the callback will hit use-after-free. I have encountered this when migrating the wayland backend to the head-based API, using --sprawl, and closing/disconnecting one of the parent compositor outputs. Store the idle_repaint callback source, and destroy it in weston_output_release(), ensuring we don't get a stale call to start_repaint_loop later. Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Reviewed-by: Ian Ray <ian.ray@ge.com> Reviewed-by: Daniel Stone <daniels@collabora.com> Acked-by: Derek Foreman <derekf@osg.samsung.com>
-rw-r--r--libweston/compositor.c8
-rw-r--r--libweston/compositor.h3
2 files changed, 10 insertions, 1 deletions
diff --git a/libweston/compositor.c b/libweston/compositor.c
index 2ec7f8e0..4a1d568a 100644
--- a/libweston/compositor.c
+++ b/libweston/compositor.c
@@ -2592,6 +2592,7 @@ idle_repaint(void *data)
assert(output->repaint_status == REPAINT_BEGIN_FROM_IDLE);
output->repaint_status = REPAINT_AWAITING_COMPLETION;
+ output->idle_repaint_source = NULL;
output->start_repaint_loop(output);
}
@@ -2716,7 +2717,9 @@ weston_output_schedule_repaint(struct weston_output *output)
return;
output->repaint_status = REPAINT_BEGIN_FROM_IDLE;
- wl_event_loop_add_idle(loop, idle_repaint, output);
+ assert(!output->idle_repaint_source);
+ output->idle_repaint_source = wl_event_loop_add_idle(loop, idle_repaint,
+ output);
TL_POINT("core_repaint_enter_loop", TLP_OUTPUT(output), TLP_END);
}
@@ -5676,6 +5679,9 @@ weston_output_release(struct weston_output *output)
output->destroying = 1;
+ if (output->idle_repaint_source)
+ wl_event_source_remove(output->idle_repaint_source);
+
if (output->enabled)
weston_compositor_remove_output(output);
diff --git a/libweston/compositor.h b/libweston/compositor.h
index 5ee7fdfd..869740df 100644
--- a/libweston/compositor.h
+++ b/libweston/compositor.h
@@ -216,6 +216,9 @@ struct weston_output {
* next repaint should be run */
struct timespec next_repaint;
+ /** For cancelling the idle_repaint callback on output destruction. */
+ struct wl_event_source *idle_repaint_source;
+
struct weston_output_zoom zoom;
int dirty;
struct wl_signal frame_signal;