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>
dev
Pekka Paalanen 7 years ago
parent 586e1ac791
commit dcbcfc7f67
  1. 8
      libweston/compositor.c
  2. 3
      libweston/compositor.h

@ -2592,6 +2592,7 @@ idle_repaint(void *data)
assert(output->repaint_status == REPAINT_BEGIN_FROM_IDLE); assert(output->repaint_status == REPAINT_BEGIN_FROM_IDLE);
output->repaint_status = REPAINT_AWAITING_COMPLETION; output->repaint_status = REPAINT_AWAITING_COMPLETION;
output->idle_repaint_source = NULL;
output->start_repaint_loop(output); output->start_repaint_loop(output);
} }
@ -2716,7 +2717,9 @@ weston_output_schedule_repaint(struct weston_output *output)
return; return;
output->repaint_status = REPAINT_BEGIN_FROM_IDLE; 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); 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; output->destroying = 1;
if (output->idle_repaint_source)
wl_event_source_remove(output->idle_repaint_source);
if (output->enabled) if (output->enabled)
weston_compositor_remove_output(output); weston_compositor_remove_output(output);

@ -216,6 +216,9 @@ struct weston_output {
* next repaint should be run */ * next repaint should be run */
struct timespec next_repaint; 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; struct weston_output_zoom zoom;
int dirty; int dirty;
struct wl_signal frame_signal; struct wl_signal frame_signal;

Loading…
Cancel
Save