From: Xiong Zhang Date: Fri, 11 Oct 2013 06:43:07 +0000 (+0800) Subject: compositor-drm: Avoid output_destroy happened before page_flip event X-Git-Tag: upstream/0.1.8~869 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=abd5d47b3b3ce45be81adf04dd9d9730a9d3fd32;p=profile%2Fivi%2Fweston-ivi-shell.git compositor-drm: Avoid output_destroy happened before page_flip event Currently there is no guarentee that output remove event always happend after page_flip event on the same output. So if the following situation occur: first: unplug a output second: output remove event arrive, output_destrory called adn free output third: page_flip event arrive on the destroyed output the segment fault will happpen in page_flip_handler(). This patch add a variable drm_compositor->destroy_pending, if page flip event is pending when output remove event arrive, output_destroy will be delayed until page flip finished. Signed-off-by: Xiong Zhang --- diff --git a/src/compositor-drm.c b/src/compositor-drm.c index 0ac5efa..ffdec89 100644 --- a/src/compositor-drm.c +++ b/src/compositor-drm.c @@ -149,6 +149,7 @@ struct drm_output { int vblank_pending; int page_flip_pending; + int destroy_pending; struct gbm_surface *surface; struct gbm_bo *cursor_bo[2]; @@ -577,6 +578,9 @@ drm_output_repaint(struct weston_output *output_base, struct drm_mode *mode; int ret = 0; + if (output->destroy_pending) + return; + if (!output->next) drm_output_render(output, damage); if (!output->next) @@ -664,6 +668,9 @@ drm_output_start_repaint_loop(struct weston_output *output_base) struct timespec ts; + if (output->destroy_pending) + return; + if (!output->current) { /* We can't page flip if there's no mode set */ uint32_t msec; @@ -704,6 +711,9 @@ vblank_handler(int fd, unsigned int frame, unsigned int sec, unsigned int usec, } static void +drm_output_destroy(struct weston_output *output_base); + +static void page_flip_handler(int fd, unsigned int frame, unsigned int sec, unsigned int usec, void *data) { @@ -721,7 +731,9 @@ page_flip_handler(int fd, unsigned int frame, output->page_flip_pending = 0; - if (!output->vblank_pending) { + if (output->destroy_pending) + drm_output_destroy(&output->base); + else if (!output->vblank_pending) { msecs = sec * 1000 + usec / 1000; weston_output_finish_frame(&output->base, msecs); @@ -1063,6 +1075,12 @@ drm_output_destroy(struct weston_output *output_base) (struct drm_compositor *) output->base.compositor; drmModeCrtcPtr origcrtc = output->original_crtc; + if (output->page_flip_pending) { + output->destroy_pending = 1; + weston_log("destroy output while page flip pending\n"); + return; + } + if (output->backlight) backlight_destroy(output->backlight);