From e7f804e9fc5b7d173fc93c210a840627eb996f2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Thu, 6 Feb 2020 21:34:39 +0100 Subject: [PATCH] device: Cancel the ongoing operation when releasing the device If a device is currently verifying, identifying or enrolling we may want the user to stop the operation before we actually release the device. Otherwise we may end-up in trying to close (failing) the internal device, while fprintd is still considering the device active, causing a dead-lock (the device can't be released, but neither claimed again or stop the current action). In fact calling Claim() -> EnrollStart() -> Release(), we would fail with the error net.reactivated.Fprint.Error.Internal: Release failed with error: The device is still busy with another operation, please try again later. (36)" However, if we try to call VerifyStop, after this error, we'd fail because for the fprintd logic, the device is not claimed anymore, but actually closed, and we'd need to claim it again, but... That would still cause an internal error. To avoid this, in case Relase() is called cancel the ongoing operation, and wait until it's done before completing the release call. --- src/device.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/device.c b/src/device.c index a4a6632..71e9514 100644 --- a/src/device.c +++ b/src/device.c @@ -562,7 +562,7 @@ _fprint_device_client_vanished (GDBusConnection *connection, } if (!fp_device_close_sync (priv->dev, NULL, &error)) - g_warning ("Error closing device after disconnect: %s", error->message); + g_debug ("Error closing device after disconnect: %s", error->message); g_clear_pointer(&priv->session, session_data_free); } @@ -716,6 +716,19 @@ static void fprint_device_release(FprintDevice *rdev, return; } + if (priv->current_cancellable) { + if (priv->current_action == ACTION_ENROLL) { + g_warning("Enrollment was in progress, stopping it"); + } else if (priv->current_action == ACTION_IDENTIFY || + priv->current_action == ACTION_VERIFY) { + g_warning("Verification was in progress, stopping it"); + } + + g_cancellable_cancel (priv->current_cancellable); + while (priv->current_action != ACTION_NONE) + g_main_context_iteration (NULL, TRUE); + } + priv->session->context = context; fp_device_close (priv->dev, NULL, (GAsyncReadyCallback) dev_close_cb, rdev); }