]> git.ipfire.org Git - thirdparty/plymouth.git/commitdiff
ply-throbber: Do not redraw when we need to stop throbbing on free
authorHans de Goede <hdegoede@redhat.com>
Tue, 18 Feb 2020 10:51:03 +0000 (11:51 +0100)
committerRay Strode <halfline@gmail.com>
Tue, 10 Mar 2020 23:51:38 +0000 (23:51 +0000)
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 <hdegoede@redhat.com>
src/libply-splash-graphics/ply-throbber.c

index a4311fdab859141a0cc7a30c9e541f62ff2b7244..bf0855ea3fc58264df1330cf3e732ae9162adaa8 100644 (file)
@@ -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;
         }