mirror of
https://gitlab.com/mishakmak/pam-fprint-grosshack.git
synced 2026-04-09 04:13:33 +02:00
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:
27
src/device.c
27
src/device.c
@ -794,15 +794,30 @@ _fprint_device_client_vanished (GDBusConnection *connection,
|
|||||||
if (session != NULL &&
|
if (session != NULL &&
|
||||||
g_strcmp0 (session->sender, name) == 0)
|
g_strcmp0 (session->sender, name) == 0)
|
||||||
{
|
{
|
||||||
while (priv->current_action != ACTION_NONE)
|
g_cancellable_cancel (priv->current_cancellable);
|
||||||
{
|
|
||||||
/* OPEN/CLOSE are not cancellable, we just need to wait */
|
|
||||||
if (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
|
/* The session may have disappeared at this point if the device
|
||||||
* was already closing. */
|
* was already closing. */
|
||||||
g_clear_pointer (&session, session_data_unref);
|
g_clear_pointer (&session, session_data_unref);
|
||||||
|
|||||||
Reference in New Issue
Block a user