From 82a1aaaaddeb4dc65728c28d6ccc776f38cd6f5d Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 18 Feb 2020 11:51:03 +0100 Subject: [PATCH 3/7] ply-throbber: Do not redraw when we need to stop throbbing on free One case where the various widgets are being freed is the pixel-display-s being removed because of a monitor being hot(un)plugged. When the monitor configuration changes ply-device-manager removes all old pixel-displays and then adds the pixel-displays from the new config. Calling ply_pixel_display_draw_area on a pixel-display which is about to be freed is a bad idea, if the monitor was actually unplugged this leads to various sort of errors, including crashes in some cases. ply-throbber is the only (older) widget which does a redraw on free, this likely was not noticed until now because typically the throbber will already have been stopped on free. This commit adds a redraw parameter to ply_throbber_stop_now and sets this to false when calling ply_throbber_stop_now from ply_throbber_free. This fixes plymouth sometimes crashing when monitors are hot(un)plugged while plymouth is running. Signed-off-by: Hans de Goede --- src/libply-splash-graphics/ply-throbber.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/libply-splash-graphics/ply-throbber.c b/src/libply-splash-graphics/ply-throbber.c index a4311fd..bf0855e 100644 --- a/src/libply-splash-graphics/ply-throbber.c +++ b/src/libply-splash-graphics/ply-throbber.c @@ -78,7 +78,7 @@ struct _ply_throbber uint32_t is_stopped : 1; }; -static void ply_throbber_stop_now (ply_throbber_t *throbber); +static void ply_throbber_stop_now (ply_throbber_t *throbber, bool redraw); ply_throbber_t * ply_throbber_new (const char *image_dir, @@ -126,7 +126,7 @@ ply_throbber_free (ply_throbber_t *throbber) return; if (!throbber->is_stopped) - ply_throbber_stop_now (throbber); + ply_throbber_stop_now (throbber, false); ply_throbber_remove_frames (throbber); ply_array_free (throbber->frames); @@ -324,15 +324,18 @@ ply_throbber_start (ply_throbber_t *throbber, } static void -ply_throbber_stop_now (ply_throbber_t *throbber) +ply_throbber_stop_now (ply_throbber_t *throbber, bool redraw) { throbber->is_stopped = true; - ply_pixel_display_draw_area (throbber->display, - throbber->x, - throbber->y, - throbber->frame_area.width, - throbber->frame_area.height); + if (redraw) { + ply_pixel_display_draw_area (throbber->display, + throbber->x, + throbber->y, + throbber->frame_area.width, + throbber->frame_area.height); + } + if (throbber->loop != NULL) { ply_event_loop_stop_watching_for_timeout (throbber->loop, (ply_event_loop_timeout_handler_t) @@ -356,7 +359,7 @@ ply_throbber_stop (ply_throbber_t *throbber, } if (stop_trigger == NULL) { - ply_throbber_stop_now (throbber); + ply_throbber_stop_now (throbber, true); return; } -- 2.25.1