]> git.ipfire.org Git - thirdparty/plymouth.git/commitdiff
device-manager: don't watch for udev events when deactivated
authorRay Strode <rstrode@redhat.com>
Wed, 10 Oct 2018 19:07:37 +0000 (20:07 +0100)
committerIain Lane <iain.lane@canonical.com>
Wed, 10 Oct 2018 19:09:52 +0000 (20:09 +0100)
If a device gets added when we're already deactivated, plymouth shouldn't
process the device, since processing it effectively activates plymouth.

This commit pulls the udev monitor fd out of the event loop while
plymouth is deactivated so new events are deferred until reactivation.

Modified by Iain Lane <iain.lane@canonical.com>: Also deactivate the
timer that finds all devices known to udev after an interval, when
paused.

src/libply-splash-core/ply-device-manager.c
src/libply-splash-core/ply-device-manager.h
src/main.c

index 18612acde8b8c54f178aad8e5f4174f145c35417..55248ac1708d1c3fe6a5c72d2610ca0a2a63525d 100644 (file)
@@ -63,6 +63,7 @@ struct _ply_device_manager
         ply_list_t                *pixel_displays;
         struct udev               *udev_context;
         struct udev_monitor       *udev_monitor;
+        ply_fd_watch_t            *fd_watch;
 
         ply_keyboard_added_handler_t         keyboard_added_handler;
         ply_keyboard_removed_handler_t       keyboard_removed_handler;
@@ -77,6 +78,9 @@ struct _ply_device_manager
         uint32_t                    serial_consoles_detected : 1;
         uint32_t                    renderers_activated : 1;
         uint32_t                    keyboards_activated : 1;
+
+        uint32_t                    paused : 1;
+        uint32_t                    device_timeout_elapsed : 1;
 };
 
 static void
@@ -375,23 +379,38 @@ watch_for_udev_events (ply_device_manager_t *manager)
         assert (manager != NULL);
         assert (manager->udev_monitor == NULL);
 
+        if (manager->fd_watch != NULL)
+                return;
+
         ply_trace ("watching for udev graphics device add and remove events");
 
-        manager->udev_monitor = udev_monitor_new_from_netlink (manager->udev_context, "udev");
+        if (manager->udev_monitor == NULL) {
+                manager->udev_monitor = udev_monitor_new_from_netlink (manager->udev_context, "udev");
 
-        udev_monitor_filter_add_match_subsystem_devtype (manager->udev_monitor, SUBSYSTEM_DRM, NULL);
-        udev_monitor_filter_add_match_subsystem_devtype (manager->udev_monitor, SUBSYSTEM_FRAME_BUFFER, NULL);
-        udev_monitor_filter_add_match_tag (manager->udev_monitor, "seat");
-        udev_monitor_enable_receiving (manager->udev_monitor);
+                udev_monitor_filter_add_match_subsystem_devtype (manager->udev_monitor, SUBSYSTEM_DRM, NULL);
+                udev_monitor_filter_add_match_subsystem_devtype (manager->udev_monitor, SUBSYSTEM_FRAME_BUFFER, NULL);
+                udev_monitor_filter_add_match_tag (manager->udev_monitor, "seat");
+                udev_monitor_enable_receiving (manager->udev_monitor);
+        }
 
         fd = udev_monitor_get_fd (manager->udev_monitor);
-        ply_event_loop_watch_fd (manager->loop,
-                                 fd,
-                                 PLY_EVENT_LOOP_FD_STATUS_HAS_DATA,
-                                 (ply_event_handler_t)
-                                 on_udev_event,
-                                 NULL,
-                                 manager);
+        manager->fd_watch = ply_event_loop_watch_fd (manager->loop,
+                                                     fd,
+                                                     PLY_EVENT_LOOP_FD_STATUS_HAS_DATA,
+                                                     (ply_event_handler_t)
+                                                     on_udev_event,
+                                                     NULL,
+                                                     manager);
+}
+
+static void
+stop_watching_for_udev_events (ply_device_manager_t *manager)
+{
+        if (manager->fd_watch == NULL)
+                return;
+
+        ply_event_loop_stop_watching_fd (manager->loop, manager->fd_watch);
+        manager->fd_watch = NULL;
 }
 #endif
 
@@ -801,6 +820,13 @@ create_devices_from_udev (ply_device_manager_t *manager)
 {
         bool found_drm_device, found_fb_device;
 
+        manager->device_timeout_elapsed = true;
+
+        if (manager->paused) {
+                ply_trace ("create_devices_from_udev timeout elapsed while paused, deferring execution");
+                return;
+        }
+
         ply_trace ("Timeout elapsed, looking for devices from udev");
 
         found_drm_device = create_devices_for_subsystem (manager, SUBSYSTEM_DRM);
@@ -992,3 +1018,27 @@ ply_device_manager_deactivate_keyboards (ply_device_manager_t *manager)
 
         manager->keyboards_activated = false;
 }
+
+void
+ply_device_manager_pause (ply_device_manager_t *manager)
+{
+        ply_trace ("ply_device_manager_pause() called, stopping watching for udev events");
+        manager->paused = true;
+#ifdef HAVE_UDEV
+        stop_watching_for_udev_events (manager);
+#endif
+}
+
+void
+ply_device_manager_unpause (ply_device_manager_t *manager)
+{
+        ply_trace ("ply_device_manager_unpause() called, resuming watching for udev events");
+        manager->paused = false;
+#ifdef HAVE_UDEV
+        if (manager->device_timeout_elapsed) {
+                ply_trace ("ply_device_manager_unpause(): timeout elapsed while paused, looking for udev devices");
+                create_devices_from_udev (manager);
+        }
+        watch_for_udev_events (manager);
+#endif
+}
index ad058971dd9b9ca16277d2fc205ad7be3423c1e0..389b636f813fd1bcf176fa8bd9c45e81cbedcf85 100644 (file)
@@ -55,6 +55,8 @@ void ply_device_manager_watch_devices (ply_device_manager_t                *mana
                                        ply_text_display_added_handler_t     text_display_added_handler,
                                        ply_text_display_removed_handler_t   text_display_removed_handler,
                                        void                                *data);
+void ply_device_manager_pause (ply_device_manager_t *manager);
+void ply_device_manager_unpause (ply_device_manager_t *manager);
 bool ply_device_manager_has_serial_consoles (ply_device_manager_t *manager);
 bool ply_device_manager_has_displays (ply_device_manager_t *manager);
 ply_list_t *ply_device_manager_get_keyboards (ply_device_manager_t *manager);
index 0564e1567462b36492d9a8901fa166d4513a07de..47157bc21c9f81fc10a4d3593fea9a44c5e48aeb 100644 (file)
@@ -1347,6 +1347,7 @@ on_deactivate (state_t       *state,
         ply_trace ("deactivating");
         cancel_pending_delayed_show (state);
 
+        ply_device_manager_pause (state->device_manager);
         ply_device_manager_deactivate_keyboards (state->device_manager);
 
         if (state->boot_splash != NULL) {
@@ -1382,6 +1383,8 @@ on_reactivate (state_t *state)
         if (state->boot_splash && ply_boot_splash_uses_pixel_displays (state->boot_splash))
                 ply_device_manager_activate_renderers (state->device_manager);
 
+        ply_device_manager_unpause (state->device_manager);
+
         state->is_inactive = false;
 
         update_display (state);