From 4bc5213e08a1edea95352b73f750a0e2c276a655 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Fri, 26 Jun 2026 14:20:29 +0200 Subject: [PATCH] egis_etu905: Split cancellable handling in commands cancel command cannot be cancellable, while we want others to be, so let's split the two cases, and handle them separately --- libfprint/drivers/egismoc/egis_etu905.c | 50 ++++++++++++++++++------- 1 file changed, 36 insertions(+), 14 deletions(-) diff --git a/libfprint/drivers/egismoc/egis_etu905.c b/libfprint/drivers/egismoc/egis_etu905.c index 8250dc4c..1cd06b73 100644 --- a/libfprint/drivers/egismoc/egis_etu905.c +++ b/libfprint/drivers/egismoc/egis_etu905.c @@ -52,6 +52,7 @@ typedef struct egis_etu905_command_data { SynCmdMsgCallback callback; FpiUsbTransfer *cmd_transfer; + GCancellable *cancellable; guchar *buffer_in; gsize length_in; } CommandData; @@ -60,6 +61,7 @@ static void egis_etu905_command_data_free (CommandData *data) { g_clear_pointer (&data->cmd_transfer, fpi_usb_transfer_unref); + g_clear_object (&data->cancellable); g_free (data->buffer_in); g_free (data); } @@ -264,7 +266,7 @@ egis_etu905_cmd_run_state (FpiSsm *ssm, transfer->ssm = ssm; fpi_usb_transfer_submit (g_steal_pointer (&transfer), EGIS_ETU905_USB_SEND_TIMEOUT, - fpi_device_get_cancellable (device), + data->cancellable, fpi_ssm_usb_transfer_cb, NULL); break; @@ -280,7 +282,7 @@ egis_etu905_cmd_run_state (FpiSsm *ssm, EGIS_ETU905_USB_IN_RECV_LENGTH); fpi_usb_transfer_submit (g_steal_pointer (&transfer), EGIS_ETU905_USB_RECV_TIMEOUT, - fpi_device_get_cancellable (device), + data->cancellable, egis_etu905_cmd_receive_cb, fpi_ssm_get_data (ssm)); break; @@ -329,10 +331,11 @@ egis_etu905_get_check_bytes (FpiByteReader *reader) } static void -egis_etu905_exec_cmd (FpDevice *device, - const guchar *cmd, - const gsize cmd_length, - SynCmdMsgCallback callback) +egis_etu905_exec_cmd_full (FpDevice *device, + const guchar *cmd, + const gsize cmd_length, + SynCmdMsgCallback callback, + GCancellable *cancellable) { g_auto(FpiByteWriter) writer = {0}; g_autoptr(FpiUsbTransfer) transfer = NULL; @@ -382,6 +385,7 @@ egis_etu905_exec_cmd (FpDevice *device, * (e.g. an in-progress operation and a cancellation) cannot collide. */ data = g_new0 (CommandData, 1); data->callback = callback; + g_set_object (&data->cancellable, cancellable); if (written) { @@ -407,6 +411,16 @@ egis_etu905_exec_cmd (FpDevice *device, fpi_ssm_mark_failed (ssm, fpi_device_error_new (FP_DEVICE_ERROR_PROTO)); } +static inline void +egis_etu905_exec_cmd (FpDevice *device, + const guchar *cmd, + const gsize cmd_length, + SynCmdMsgCallback callback) +{ + egis_etu905_exec_cmd_full (device, cmd, cmd_length, callback, + fpi_device_get_cancellable (device)); +} + static void egis_etu905_set_print_data (FpPrint *print, const gchar *device_print_id, @@ -1636,19 +1650,27 @@ egis_etu905_cancel (FpDevice *device) fp_dbg ("Cancelling action %d", action); + /* The cancellation commands must reach the device to abort the ongoing + * sensor operation. By the time we get here the device cancellable is + * already cancelled (it aborted the in-flight operation transfer), so we + * must not bind these commands to it or they would never be sent. + * Cancellation is effectively non-cancellable; the commands are allowed to + * fail (no callback), the device is reset by the next operation anyway. */ if (action == FPI_DEVICE_ACTION_ENROLL) { - egis_etu905_exec_cmd (device, - cmd_enroll_discard, - G_N_ELEMENTS (cmd_enroll_discard), - NULL); + egis_etu905_exec_cmd_full (device, + cmd_enroll_discard, + G_N_ELEMENTS (cmd_enroll_discard), + NULL, + NULL); } else if (action == FPI_DEVICE_ACTION_IDENTIFY) { - egis_etu905_exec_cmd (device, - cmd_identify_cancel, - G_N_ELEMENTS (cmd_identify_cancel), - NULL); + egis_etu905_exec_cmd_full (device, + cmd_identify_cancel, + G_N_ELEMENTS (cmd_identify_cancel), + NULL, + NULL); } }