mirror of
https://gitlab.freedesktop.org/libfprint/libfprint.git
synced 2026-05-07 13:28:06 +02:00
context: Simplify handling of removal signals
We used to notify device removed signal in an idle to ensure that this happened before the context device-removed signal, however this can be achieved also using the after-callbacks without having to imply further idles that complicates the context destruction handling, also causing that a device that has been removed is returned by get_devices() for longer than expected. Simplify the codepath adjusting the tests. They are still checking that the order is preserved.
This commit is contained in:
parent
3b783b9985
commit
51dd46b3d9
2 changed files with 21 additions and 96 deletions
|
|
@ -89,54 +89,17 @@ is_driver_allowed (const gchar *driver)
|
|||
return g_strv_contains ((const gchar * const *) allowlisted_drivers, driver);
|
||||
}
|
||||
|
||||
typedef struct
|
||||
static void
|
||||
remove_device (FpContext *context,
|
||||
FpDevice *device)
|
||||
{
|
||||
FpContext *context;
|
||||
FpDevice *device;
|
||||
GSource *source;
|
||||
} RemoveDeviceData;
|
||||
|
||||
static gboolean
|
||||
remove_device_idle_cb (RemoveDeviceData *data)
|
||||
{
|
||||
FpContextPrivate *priv = fp_context_get_instance_private (data->context);
|
||||
FpContextPrivate *priv = fp_context_get_instance_private (context);
|
||||
guint idx = 0;
|
||||
|
||||
g_return_val_if_fail (g_ptr_array_find (priv->devices, data->device, &idx), G_SOURCE_REMOVE);
|
||||
g_return_if_fail (g_ptr_array_find (priv->devices, device, &idx));
|
||||
|
||||
g_signal_emit (data->context, signals[DEVICE_REMOVED_SIGNAL], 0, data->device);
|
||||
g_signal_emit (context, signals[DEVICE_REMOVED_SIGNAL], 0, device);
|
||||
g_ptr_array_remove_index_fast (priv->devices, idx);
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
remove_device_data_free (RemoveDeviceData *data)
|
||||
{
|
||||
FpContextPrivate *priv = fp_context_get_instance_private (data->context);
|
||||
|
||||
priv->sources = g_slist_remove (priv->sources, data->source);
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
static void
|
||||
remove_device (FpContext *context, FpDevice *device)
|
||||
{
|
||||
g_autoptr(GSource) source = NULL;
|
||||
FpContextPrivate *priv = fp_context_get_instance_private (context);
|
||||
RemoveDeviceData *data;
|
||||
|
||||
data = g_new (RemoveDeviceData, 1);
|
||||
data->context = context;
|
||||
data->device = device;
|
||||
|
||||
source = data->source = g_idle_source_new ();
|
||||
g_source_set_callback (source,
|
||||
G_SOURCE_FUNC (remove_device_idle_cb), data,
|
||||
(GDestroyNotify) remove_device_data_free);
|
||||
g_source_attach (source, g_main_context_get_thread_default ());
|
||||
|
||||
priv->sources = g_slist_prepend (priv->sources, source);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -149,17 +112,13 @@ device_remove_on_notify_open_cb (FpContext *context, GParamSpec *pspec, FpDevice
|
|||
static void
|
||||
device_removed_cb (FpContext *context, FpDevice *device)
|
||||
{
|
||||
gboolean open = FALSE;
|
||||
|
||||
g_object_get (device, "open", &open, NULL);
|
||||
|
||||
/* Wait for device close if the device is currently still open. */
|
||||
if (open)
|
||||
if (fp_device_is_open (device))
|
||||
{
|
||||
g_signal_connect_object (device, "notify::open",
|
||||
(GCallback) device_remove_on_notify_open_cb,
|
||||
context,
|
||||
G_CONNECT_SWAPPED);
|
||||
G_CONNECT_SWAPPED | G_CONNECT_AFTER);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -195,7 +154,7 @@ async_device_init_done_cb (GObject *source_object, GAsyncResult *res, gpointer u
|
|||
g_signal_connect_object (device, "removed",
|
||||
(GCallback) device_removed_cb,
|
||||
context,
|
||||
G_CONNECT_SWAPPED);
|
||||
G_CONNECT_SWAPPED | G_CONNECT_AFTER);
|
||||
|
||||
g_signal_emit (context, signals[DEVICE_ADDED_SIGNAL], 0, device);
|
||||
}
|
||||
|
|
@ -275,8 +234,10 @@ usb_device_removed_cb (FpContext *self, GUsbDevice *device, GUsbContext *usb_ctx
|
|||
if (cls->type != FP_DEVICE_TYPE_USB)
|
||||
continue;
|
||||
|
||||
if (fpi_device_get_usb_device (dev) == device)
|
||||
fpi_device_remove (dev);
|
||||
if (fpi_device_get_usb_device (dev) != device)
|
||||
continue;
|
||||
|
||||
fpi_device_remove (dev);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -121,29 +121,21 @@ static void
|
|||
test_context_remove_device_closed (void)
|
||||
{
|
||||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||
gboolean removed;
|
||||
FpDevice *device = tctx->device;
|
||||
|
||||
tctx->user_data = NULL;
|
||||
g_signal_connect (tctx->device, "removed", (GCallback) device_removed_cb, tctx);
|
||||
g_signal_connect (tctx->fp_context, "device-removed", (GCallback) context_device_removed_cb, tctx);
|
||||
g_signal_connect (tctx->device, "removed", (GCallback) device_removed_cb, tctx);
|
||||
|
||||
/* Triggering remove on closed device. */
|
||||
fpi_device_remove (tctx->device);
|
||||
|
||||
g_assert_nonnull (tctx->device);
|
||||
g_object_get (tctx->device, "removed", &removed, NULL);
|
||||
g_assert_true (removed);
|
||||
g_assert_cmpint (GPOINTER_TO_INT (tctx->user_data), ==, DEV_REMOVED_CB);
|
||||
|
||||
/* device-removed is dispatched from idle. */
|
||||
while (g_main_context_iteration (NULL, FALSE))
|
||||
{
|
||||
}
|
||||
|
||||
/* The device is now destroyed and device-removed was called. */
|
||||
g_assert_null (tctx->device);
|
||||
g_assert_cmpint (GPOINTER_TO_INT (tctx->user_data), ==, CTX_DEVICE_REMOVED_CB);
|
||||
|
||||
g_assert_false (g_ptr_array_find (fp_context_get_devices (tctx->fp_context), device, NULL));
|
||||
|
||||
fpt_teardown_virtual_device_environment ();
|
||||
}
|
||||
|
||||
|
|
@ -165,6 +157,7 @@ test_context_remove_device_closing (void)
|
|||
g_autoptr(FptContext) tctx = fpt_context_new_with_virtual_device (FPT_VIRTUAL_DEVICE_IMAGE);
|
||||
g_autoptr(GError) close_error = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
FpDevice *device = tctx->device;
|
||||
gboolean removed;
|
||||
|
||||
tctx->user_data = NULL;
|
||||
|
|
@ -190,17 +183,11 @@ test_context_remove_device_closing (void)
|
|||
g_assert_error (close_error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_REMOVED);
|
||||
|
||||
/* Now the removed callback has been called already. */
|
||||
g_assert_nonnull (tctx->device);
|
||||
g_assert_cmpint (GPOINTER_TO_INT (tctx->user_data), ==, DEV_REMOVED_CB);
|
||||
|
||||
/* While device-removed needs another idle iteration. */
|
||||
while (g_main_context_iteration (NULL, FALSE))
|
||||
{
|
||||
}
|
||||
|
||||
g_assert_null (tctx->device);
|
||||
g_assert_cmpint (GPOINTER_TO_INT (tctx->user_data), ==, CTX_DEVICE_REMOVED_CB);
|
||||
|
||||
g_assert_false (g_ptr_array_find (fp_context_get_devices (tctx->fp_context), device, NULL));
|
||||
|
||||
fpt_teardown_virtual_device_environment ();
|
||||
}
|
||||
|
||||
|
|
@ -234,16 +221,9 @@ test_context_remove_device_open (void)
|
|||
}
|
||||
g_assert_cmpint (GPOINTER_TO_INT (tctx->user_data), ==, DEV_REMOVED_CB);
|
||||
|
||||
/* On close, the device will be removed from the context,
|
||||
* but only a main loop iteration later. */
|
||||
/* On close, the device will be removed from the context */
|
||||
fp_device_close_sync (tctx->device, NULL, &error);
|
||||
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_REMOVED);
|
||||
g_assert_nonnull (tctx->device);
|
||||
g_assert_cmpint (GPOINTER_TO_INT (tctx->user_data), ==, DEV_REMOVED_CB);
|
||||
|
||||
while (g_main_context_iteration (NULL, FALSE))
|
||||
{
|
||||
}
|
||||
g_assert_null (tctx->device);
|
||||
g_assert_cmpint (GPOINTER_TO_INT (tctx->user_data), ==, CTX_DEVICE_REMOVED_CB);
|
||||
|
||||
|
|
@ -298,14 +278,6 @@ test_context_remove_device_opening (void)
|
|||
fp_device_close_sync (tctx->device, NULL, &close_error);
|
||||
g_assert_error (close_error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_REMOVED);
|
||||
|
||||
g_assert_nonnull (tctx->device);
|
||||
g_assert_cmpint (GPOINTER_TO_INT (tctx->user_data), ==, DEV_REMOVED_CB);
|
||||
|
||||
/* The device-removed signal needs an idle iteration. */
|
||||
while (g_main_context_iteration (NULL, FALSE))
|
||||
{
|
||||
}
|
||||
|
||||
g_assert_null (tctx->device);
|
||||
g_assert_cmpint (GPOINTER_TO_INT (tctx->user_data), ==, CTX_DEVICE_REMOVED_CB);
|
||||
|
||||
|
|
@ -369,14 +341,6 @@ test_context_remove_device_active (void)
|
|||
/* Now we close the device, state remains unchanged mostly. */
|
||||
fp_device_close_sync (tctx->device, NULL, &error);
|
||||
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_REMOVED);
|
||||
g_assert_nonnull (tctx->device);
|
||||
g_assert_cmpint (GPOINTER_TO_INT (tctx->user_data), ==, DEV_REMOVED_CB);
|
||||
|
||||
/* And "device-removed" is called */
|
||||
while (g_main_context_iteration (NULL, FALSE))
|
||||
{
|
||||
}
|
||||
|
||||
g_assert_null (tctx->device);
|
||||
g_assert_cmpint (GPOINTER_TO_INT (tctx->user_data), ==, CTX_DEVICE_REMOVED_CB);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue