summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Berg <bberg@redhat.com>2021-11-24 12:09:18 +0100
committerBenjamin Berg <benjamin@sipsolutions.net>2021-12-01 15:29:18 +0000
commit05fd2c58cb9965b60e3b39de93e06abfb4f286da (patch)
treecc5f7d88dffa604cc60abf3e9f486a6b26cc3bb1
parenta033154b2eaae1cba6259fb414887a7865c8bb80 (diff)
context: Ensure mainloop is idle before enumeration completes
This ensures that we have processed all hotplug events before considering enumeration to be complete. This is important due to USB persist being turned off. At resume time, devices will disappear and immediately re-appear. In this situatoin, enumerate could first see the old state with a removed device resulting in it to not be discovered. As a hotplug event is semingly emitted by the kernel immediately, we can simply make sure to process this hotplug event before returning from enumerate. Closes: fprintd#119
-rw-r--r--libfprint/fp-context.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/libfprint/fp-context.c b/libfprint/fp-context.c
index d4bd000..1f32215 100644
--- a/libfprint/fp-context.c
+++ b/libfprint/fp-context.c
@@ -426,6 +426,7 @@ void
fp_context_enumerate (FpContext *context)
{
FpContextPrivate *priv = fp_context_get_instance_private (context);
+ gboolean dispatched;
gint i;
g_return_if_fail (FP_IS_CONTEXT (context));
@@ -564,8 +565,19 @@ fp_context_enumerate (FpContext *context)
}
#endif
- while (priv->pending_devices)
- g_main_context_iteration (NULL, TRUE);
+ /* Iterate until 1. we have no pending devices, and 2. the mainloop is idle
+ * This takes care of processing hotplug events that happened during
+ * enumeration.
+ * This is important due to USB `persist` being turned off. At resume time,
+ * devices will disappear and immediately re-appear. In this situation,
+ * enumerate could first see the old state with a removed device resulting
+ * in it to not be discovered.
+ * As a hotplug event is seemingly emitted by the kernel immediately, we can
+ * simply make sure to process all events before returning from enumerate.
+ */
+ dispatched = TRUE;
+ while (priv->pending_devices || dispatched)
+ dispatched = g_main_context_iteration (NULL, !!priv->pending_devices);
}
/**