aes3k: Fix cancellation logic of aes3k driver
The change_state function is called synchronously from the image_captured callback. This means that deactivation of the device happens during the img_cb function, causing the USB transfer to be re-registered even though the device is already deactivating. There are various ways to fix this, but it makes sense to directly bind the cancellation to the deactivation. So create a cancellable that we cancel at deactivation time, and make sure we always deactivate by going through cancellation. closes: #306
This commit is contained in:
parent
3962372f47
commit
bcce8876e2
1 changed files with 14 additions and 18 deletions
|
@ -42,8 +42,7 @@
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
FpiUsbTransfer *img_trf;
|
GCancellable *img_trf_cancel;
|
||||||
gboolean deactivating;
|
|
||||||
} FpiDeviceAes3kPrivate;
|
} FpiDeviceAes3kPrivate;
|
||||||
|
|
||||||
#define CTRL_TIMEOUT 1000
|
#define CTRL_TIMEOUT 1000
|
||||||
|
@ -77,24 +76,20 @@ img_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
{
|
{
|
||||||
FpImageDevice *dev = FP_IMAGE_DEVICE (device);
|
FpImageDevice *dev = FP_IMAGE_DEVICE (device);
|
||||||
FpiDeviceAes3k *self = FPI_DEVICE_AES3K (device);
|
FpiDeviceAes3k *self = FPI_DEVICE_AES3K (device);
|
||||||
FpiDeviceAes3kPrivate *priv = fpi_device_aes3k_get_instance_private (self);
|
|
||||||
FpiDeviceAes3kClass *cls = FPI_DEVICE_AES3K_GET_CLASS (self);
|
FpiDeviceAes3kClass *cls = FPI_DEVICE_AES3K_GET_CLASS (self);
|
||||||
unsigned char *ptr = transfer->buffer;
|
unsigned char *ptr = transfer->buffer;
|
||||||
FpImage *tmp;
|
FpImage *tmp;
|
||||||
FpImage *img;
|
FpImage *img;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
priv->img_trf = NULL;
|
|
||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
{
|
{
|
||||||
if (g_error_matches (error,
|
if (g_error_matches (error,
|
||||||
G_IO_ERROR,
|
G_IO_ERROR,
|
||||||
G_IO_ERROR_CANCELLED))
|
G_IO_ERROR_CANCELLED))
|
||||||
{
|
{
|
||||||
/* Deactivation was completed. */
|
/* Cancellation implies we are deactivating. */
|
||||||
g_error_free (error);
|
g_error_free (error);
|
||||||
if (priv->deactivating)
|
|
||||||
fpi_image_device_deactivate_complete (dev, NULL);
|
fpi_image_device_deactivate_complete (dev, NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -126,21 +121,23 @@ img_cb (FpiUsbTransfer *transfer, FpDevice *device,
|
||||||
* it really has, then restart the capture */
|
* it really has, then restart the capture */
|
||||||
fpi_image_device_report_finger_status (dev, FALSE);
|
fpi_image_device_report_finger_status (dev, FALSE);
|
||||||
|
|
||||||
|
/* Note: We always restart the transfer, it may already be cancelled though. */
|
||||||
do_capture (dev);
|
do_capture (dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
do_capture (FpImageDevice *dev)
|
do_capture (FpImageDevice *dev)
|
||||||
{
|
{
|
||||||
|
g_autoptr(FpiUsbTransfer) img_trf = NULL;
|
||||||
FpiDeviceAes3k *self = FPI_DEVICE_AES3K (dev);
|
FpiDeviceAes3k *self = FPI_DEVICE_AES3K (dev);
|
||||||
FpiDeviceAes3kPrivate *priv = fpi_device_aes3k_get_instance_private (self);
|
FpiDeviceAes3kPrivate *priv = fpi_device_aes3k_get_instance_private (self);
|
||||||
FpiDeviceAes3kClass *cls = FPI_DEVICE_AES3K_GET_CLASS (self);
|
FpiDeviceAes3kClass *cls = FPI_DEVICE_AES3K_GET_CLASS (self);
|
||||||
|
|
||||||
priv->img_trf = fpi_usb_transfer_new (FP_DEVICE (dev));
|
img_trf = fpi_usb_transfer_new (FP_DEVICE (dev));
|
||||||
fpi_usb_transfer_fill_bulk (priv->img_trf, EP_IN, cls->data_buflen);
|
fpi_usb_transfer_fill_bulk (img_trf, EP_IN, cls->data_buflen);
|
||||||
priv->img_trf->short_is_error = TRUE;
|
img_trf->short_is_error = TRUE;
|
||||||
fpi_usb_transfer_submit (priv->img_trf, 0,
|
fpi_usb_transfer_submit (g_steal_pointer (&img_trf), 0,
|
||||||
fpi_device_get_cancellable (FP_DEVICE (dev)),
|
priv->img_trf_cancel,
|
||||||
img_cb, NULL);
|
img_cb, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,7 +156,8 @@ aes3k_dev_activate (FpImageDevice *dev)
|
||||||
FpiDeviceAes3kPrivate *priv = fpi_device_aes3k_get_instance_private (self);
|
FpiDeviceAes3kPrivate *priv = fpi_device_aes3k_get_instance_private (self);
|
||||||
FpiDeviceAes3kClass *cls = FPI_DEVICE_AES3K_GET_CLASS (self);
|
FpiDeviceAes3kClass *cls = FPI_DEVICE_AES3K_GET_CLASS (self);
|
||||||
|
|
||||||
priv->deactivating = FALSE;
|
g_assert (!priv->img_trf_cancel);
|
||||||
|
priv->img_trf_cancel = g_cancellable_new ();
|
||||||
aes_write_regv (dev, cls->init_reqs, cls->init_reqs_len, init_reqs_cb, NULL);
|
aes_write_regv (dev, cls->init_reqs, cls->init_reqs_len, init_reqs_cb, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,10 +167,8 @@ aes3k_dev_deactivate (FpImageDevice *dev)
|
||||||
FpiDeviceAes3k *self = FPI_DEVICE_AES3K (dev);
|
FpiDeviceAes3k *self = FPI_DEVICE_AES3K (dev);
|
||||||
FpiDeviceAes3kPrivate *priv = fpi_device_aes3k_get_instance_private (self);
|
FpiDeviceAes3kPrivate *priv = fpi_device_aes3k_get_instance_private (self);
|
||||||
|
|
||||||
priv->deactivating = TRUE;
|
/* Deactivation always finishes from the cancellation handler */
|
||||||
if (priv->img_trf)
|
g_cancellable_cancel (priv->img_trf_cancel);
|
||||||
return;
|
|
||||||
fpi_image_device_deactivate_complete (dev, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
Loading…
Reference in a new issue