aes2550: Complete deactivation from dev_deactivate on broken loops

The driver relied on a running finger-detection or capture callback to
observe the deactivating flag and call complete_deactivation(). When the
async loop was broken by a session error from a terminal callback (such
as capture_sm_complete), no further iteration was left to notice the
flag, so the deactivation never completed.

Rather than scatter complete_deactivation() calls after every
fpi_image_device_session_error(), track whether an operation is actually
pending with an "active" flag and let dev_deactivate() complete the
request itself when nothing is in flight.

This keeps the deactivation lifecycle owned by dev_deactivate.
This commit is contained in:
Marco Trevisan (Treviño)
2026-07-23 14:36:02 +02:00
parent 87a7023831
commit 833d39ab59
+41 -14
View File
@@ -57,6 +57,7 @@ struct _FpiDeviceAes2550
GSList *strips; GSList *strips;
size_t strips_len; size_t strips_len;
gboolean active;
gboolean deactivating; gboolean deactivating;
int heartbeat_cnt; int heartbeat_cnt;
}; };
@@ -91,14 +92,21 @@ finger_det_data_cb (FpiUsbTransfer *transfer, FpDevice *device,
gpointer user_data, GError *error) gpointer user_data, GError *error)
{ {
FpImageDevice *dev = FP_IMAGE_DEVICE (device); FpImageDevice *dev = FP_IMAGE_DEVICE (device);
FpiDeviceAes2550 *self = FPI_DEVICE_AES2550 (device);
unsigned char *data = transfer->buffer; unsigned char *data = transfer->buffer;
if (error) if (error)
{ {
/* Ensure deactivation completes even though the finger-detect /* The finger-detect loop is broken; it no longer has a pending
* loop is broken by the session error. */ * operation. Clear the active flag so that the deactivation
fpi_image_device_session_error (dev, error); * triggered by the session error (or an in-flight cancellation)
complete_deactivation (dev); * can complete. */
self->active = FALSE;
if (self->deactivating)
complete_deactivation (dev);
else
fpi_image_device_session_error (dev, error);
return; return;
} }
@@ -125,13 +133,20 @@ finger_det_reqs_cb (FpiUsbTransfer *t, FpDevice *device,
{ {
FpiUsbTransfer *transfer; FpiUsbTransfer *transfer;
FpImageDevice *dev = FP_IMAGE_DEVICE (device); FpImageDevice *dev = FP_IMAGE_DEVICE (device);
FpiDeviceAes2550 *self = FPI_DEVICE_AES2550 (device);
if (error) if (error)
{ {
/* Ensure deactivation completes even though the finger-detect /* The finger-detect loop is broken; it no longer has a pending
* loop is broken by the session error. */ * operation. Clear the active flag so that the deactivation
fpi_image_device_session_error (dev, error); * triggered by the session error (or an in-flight cancellation)
complete_deactivation (dev); * can complete. */
self->active = FALSE;
if (self->deactivating)
complete_deactivation (dev);
else
fpi_image_device_session_error (dev, error);
return; return;
} }
@@ -383,12 +398,12 @@ capture_sm_complete (FpiSsm *ssm, FpDevice *_dev, GError *error)
} }
else if (error) else if (error)
{ {
/* fpi_image_device_session_error() will trigger dev_deactivate() /* The capture SSM has terminated, so no completion handler is left
* which sets the deactivating flag. Since the SSM is terminating, * to observe the deactivation that the session error triggers.
* complete_deactivation() must be called here to avoid a deadlock * Clear the active flag so dev_deactivate() completes it directly.
* where nothing checks the deactivating flag. */ */
self->active = FALSE;
fpi_image_device_session_error (dev, error); fpi_image_device_session_error (dev, error);
complete_deactivation (dev);
} }
else else
{ {
@@ -506,12 +521,16 @@ activate_run_state (FpiSsm *ssm, FpDevice *dev)
static void static void
activate_sm_complete (FpiSsm *ssm, FpDevice *_dev, GError *error) activate_sm_complete (FpiSsm *ssm, FpDevice *_dev, GError *error)
{ {
FpiDeviceAes2550 *self = FPI_DEVICE_AES2550 (_dev);
FpImageDevice *dev = FP_IMAGE_DEVICE (_dev); FpImageDevice *dev = FP_IMAGE_DEVICE (_dev);
fpi_image_device_activate_complete (dev, error); fpi_image_device_activate_complete (dev, error);
if (!error) if (!error)
start_finger_detection (dev); {
self->active = TRUE;
start_finger_detection (dev);
}
} }
static void static void
@@ -528,6 +547,13 @@ dev_deactivate (FpImageDevice *dev)
{ {
FpiDeviceAes2550 *self = FPI_DEVICE_AES2550 (dev); FpiDeviceAes2550 *self = FPI_DEVICE_AES2550 (dev);
if (!self->active)
{
/* No operation is pending, so complete it right away. */
complete_deactivation (dev);
return;
}
self->deactivating = TRUE; self->deactivating = TRUE;
} }
@@ -539,6 +565,7 @@ complete_deactivation (FpImageDevice *dev)
G_DEBUG_HERE (); G_DEBUG_HERE ();
self->deactivating = FALSE; self->deactivating = FALSE;
self->active = FALSE;
g_slist_free (self->strips); g_slist_free (self->strips);
self->strips = NULL; self->strips = NULL;
self->strips_len = 0; self->strips_len = 0;