device: Fix race when client vanishes from bus

We have a condition where a client vanishing instead of cleaning up the
operation using VerifyStop would cause fprintd to hang. This only
happens if the underlying enroll/verify/identify operation has already
finished when the client vanishes.

Fix this by correctly interpreting current_cancellable as a flag for
these operations.

Fixes: #97
This commit is contained in:
Benjamin Berg
2020-12-16 11:13:20 +01:00
parent 7b7aa6e99d
commit 7c9a04c2ae

View File

@ -794,15 +794,30 @@ _fprint_device_client_vanished (GDBusConnection *connection,
if (session != NULL &&
g_strcmp0 (session->sender, name) == 0)
{
while (priv->current_action != ACTION_NONE)
{
/* OPEN/CLOSE are not cancellable, we just need to wait */
if (priv->current_cancellable)
g_cancellable_cancel (priv->current_cancellable);
g_cancellable_cancel (priv->current_cancellable);
g_main_context_iteration (NULL, TRUE);
if (!priv->current_cancellable)
{
/* This isn't optimal, but for verify/identify/enroll we expect the stop
* command. And we use current_cancellable as a flag to know that the
* underlying operation has finished already.
* If it has finished, unset the current_action. */
switch (priv->current_action)
{
case ACTION_VERIFY:
case ACTION_IDENTIFY:
case ACTION_ENROLL:
priv->current_action = ACTION_NONE;
break;
default:
break;
}
}
while (priv->current_action != ACTION_NONE)
g_main_context_iteration (NULL, TRUE);
/* The session may have disappeared at this point if the device
* was already closing. */
g_clear_pointer (&session, session_data_unref);