Skip to content

Commit 56ae75d

Browse files
author
Benjamin Berg
committed
device: Fully re-evaluate suspend/resume logic when delayed
If we delayed the suspend(/resume) call, then the circumstances may have changed. In particular, an active action may have completed already which means that the driver handler should not be called anymore.
1 parent 54a98bb commit 56ae75d

File tree

3 files changed

+108
-89
lines changed

3 files changed

+108
-89
lines changed

libfprint/fp-device-private.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,9 @@ typedef struct
130130

131131
void match_data_free (FpMatchData *match_data);
132132

133+
void fpi_device_suspend (FpDevice *device);
134+
void fpi_device_resume (FpDevice *device);
135+
133136
void fpi_device_configure_wakeup (FpDevice *device,
134137
gboolean enabled);
135138
void fpi_device_update_temp (FpDevice *device,

libfprint/fp-device.c

Lines changed: 2 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -949,16 +949,6 @@ fp_device_close_finish (FpDevice *device,
949949
return g_task_propagate_boolean (G_TASK (result), error);
950950
}
951951

952-
static void
953-
complete_suspend_resume_task (FpDevice *device)
954-
{
955-
FpDevicePrivate *priv = fp_device_get_instance_private (device);
956-
957-
g_assert (priv->suspend_resume_task);
958-
959-
g_task_return_boolean (g_steal_pointer (&priv->suspend_resume_task), TRUE);
960-
}
961-
962952
/**
963953
* fp_device_suspend:
964954
* @device: a #FpDevice
@@ -1009,48 +999,7 @@ fp_device_suspend (FpDevice *device,
1009999

10101000
priv->suspend_resume_task = g_steal_pointer (&task);
10111001

1012-
/* If the device is currently idle, just complete immediately.
1013-
* For long running tasks, call the driver handler right away, for short
1014-
* tasks, wait for completion and then return the task.
1015-
*/
1016-
switch (priv->current_action)
1017-
{
1018-
case FPI_DEVICE_ACTION_NONE:
1019-
fpi_device_suspend_complete (device, NULL);
1020-
break;
1021-
1022-
case FPI_DEVICE_ACTION_ENROLL:
1023-
case FPI_DEVICE_ACTION_VERIFY:
1024-
case FPI_DEVICE_ACTION_IDENTIFY:
1025-
case FPI_DEVICE_ACTION_CAPTURE:
1026-
if (FP_DEVICE_GET_CLASS (device)->suspend)
1027-
{
1028-
if (priv->critical_section)
1029-
priv->suspend_queued = TRUE;
1030-
else
1031-
FP_DEVICE_GET_CLASS (device)->suspend (device);
1032-
}
1033-
else
1034-
{
1035-
fpi_device_suspend_complete (device, fpi_device_error_new (FP_DEVICE_ERROR_NOT_SUPPORTED));
1036-
}
1037-
break;
1038-
1039-
default:
1040-
case FPI_DEVICE_ACTION_PROBE:
1041-
case FPI_DEVICE_ACTION_OPEN:
1042-
case FPI_DEVICE_ACTION_CLOSE:
1043-
case FPI_DEVICE_ACTION_DELETE:
1044-
case FPI_DEVICE_ACTION_LIST:
1045-
case FPI_DEVICE_ACTION_CLEAR_STORAGE:
1046-
g_signal_connect_object (priv->current_task,
1047-
"notify::completed",
1048-
G_CALLBACK (complete_suspend_resume_task),
1049-
device,
1050-
G_CONNECT_SWAPPED);
1051-
1052-
break;
1053-
}
1002+
fpi_device_suspend (device);
10541003
}
10551004

10561005
/**
@@ -1115,41 +1064,7 @@ fp_device_resume (FpDevice *device,
11151064

11161065
priv->suspend_resume_task = g_steal_pointer (&task);
11171066

1118-
switch (priv->current_action)
1119-
{
1120-
case FPI_DEVICE_ACTION_NONE:
1121-
fpi_device_resume_complete (device, NULL);
1122-
break;
1123-
1124-
case FPI_DEVICE_ACTION_ENROLL:
1125-
case FPI_DEVICE_ACTION_VERIFY:
1126-
case FPI_DEVICE_ACTION_IDENTIFY:
1127-
case FPI_DEVICE_ACTION_CAPTURE:
1128-
if (FP_DEVICE_GET_CLASS (device)->resume)
1129-
{
1130-
if (priv->critical_section)
1131-
priv->resume_queued = TRUE;
1132-
else
1133-
FP_DEVICE_GET_CLASS (device)->resume (device);
1134-
}
1135-
else
1136-
{
1137-
fpi_device_resume_complete (device, fpi_device_error_new (FP_DEVICE_ERROR_NOT_SUPPORTED));
1138-
}
1139-
break;
1140-
1141-
default:
1142-
case FPI_DEVICE_ACTION_PROBE:
1143-
case FPI_DEVICE_ACTION_OPEN:
1144-
case FPI_DEVICE_ACTION_CLOSE:
1145-
case FPI_DEVICE_ACTION_DELETE:
1146-
case FPI_DEVICE_ACTION_LIST:
1147-
case FPI_DEVICE_ACTION_CLEAR_STORAGE:
1148-
/* cannot happen as we make sure these tasks complete before suspend */
1149-
g_assert_not_reached ();
1150-
complete_suspend_resume_task (device);
1151-
break;
1152-
}
1067+
fpi_device_resume (device);
11531068
}
11541069

11551070
/**

libfprint/fpi-device.c

Lines changed: 103 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -866,16 +866,16 @@ fpi_device_critical_section_flush_idle_cb (FpDevice *device)
866866

867867
if (priv->suspend_queued)
868868
{
869-
cls->suspend (device);
870869
priv->suspend_queued = FALSE;
870+
fpi_device_suspend (device);
871871

872872
return G_SOURCE_CONTINUE;
873873
}
874874

875875
if (priv->resume_queued)
876876
{
877-
cls->resume (device);
878877
priv->resume_queued = FALSE;
878+
fpi_device_resume (device);
879879

880880
return G_SOURCE_CONTINUE;
881881
}
@@ -1592,6 +1592,107 @@ update_attr (const char *attr, const char *value)
15921592
return 0;
15931593
}
15941594

1595+
static void
1596+
complete_suspend_resume_task (FpDevice *device)
1597+
{
1598+
FpDevicePrivate *priv = fp_device_get_instance_private (device);
1599+
1600+
g_assert (priv->suspend_resume_task);
1601+
1602+
g_task_return_boolean (g_steal_pointer (&priv->suspend_resume_task), TRUE);
1603+
}
1604+
1605+
void
1606+
fpi_device_suspend (FpDevice *device)
1607+
{
1608+
FpDevicePrivate *priv = fp_device_get_instance_private (device);
1609+
1610+
/* If the device is currently idle, just complete immediately.
1611+
* For long running tasks, call the driver handler right away, for short
1612+
* tasks, wait for completion and then return the task.
1613+
*/
1614+
switch (priv->current_action)
1615+
{
1616+
case FPI_DEVICE_ACTION_NONE:
1617+
fpi_device_suspend_complete (device, NULL);
1618+
break;
1619+
1620+
case FPI_DEVICE_ACTION_ENROLL:
1621+
case FPI_DEVICE_ACTION_VERIFY:
1622+
case FPI_DEVICE_ACTION_IDENTIFY:
1623+
case FPI_DEVICE_ACTION_CAPTURE:
1624+
if (FP_DEVICE_GET_CLASS (device)->suspend)
1625+
{
1626+
if (priv->critical_section)
1627+
priv->suspend_queued = TRUE;
1628+
else
1629+
FP_DEVICE_GET_CLASS (device)->suspend (device);
1630+
}
1631+
else
1632+
{
1633+
fpi_device_suspend_complete (device, fpi_device_error_new (FP_DEVICE_ERROR_NOT_SUPPORTED));
1634+
}
1635+
break;
1636+
1637+
default:
1638+
case FPI_DEVICE_ACTION_PROBE:
1639+
case FPI_DEVICE_ACTION_OPEN:
1640+
case FPI_DEVICE_ACTION_CLOSE:
1641+
case FPI_DEVICE_ACTION_DELETE:
1642+
case FPI_DEVICE_ACTION_LIST:
1643+
case FPI_DEVICE_ACTION_CLEAR_STORAGE:
1644+
g_signal_connect_object (priv->current_task,
1645+
"notify::completed",
1646+
G_CALLBACK (complete_suspend_resume_task),
1647+
device,
1648+
G_CONNECT_SWAPPED);
1649+
1650+
break;
1651+
}
1652+
}
1653+
1654+
void
1655+
fpi_device_resume (FpDevice *device)
1656+
{
1657+
FpDevicePrivate *priv = fp_device_get_instance_private (device);
1658+
1659+
switch (priv->current_action)
1660+
{
1661+
case FPI_DEVICE_ACTION_NONE:
1662+
fpi_device_resume_complete (device, NULL);
1663+
break;
1664+
1665+
case FPI_DEVICE_ACTION_ENROLL:
1666+
case FPI_DEVICE_ACTION_VERIFY:
1667+
case FPI_DEVICE_ACTION_IDENTIFY:
1668+
case FPI_DEVICE_ACTION_CAPTURE:
1669+
if (FP_DEVICE_GET_CLASS (device)->resume)
1670+
{
1671+
if (priv->critical_section)
1672+
priv->resume_queued = TRUE;
1673+
else
1674+
FP_DEVICE_GET_CLASS (device)->resume (device);
1675+
}
1676+
else
1677+
{
1678+
fpi_device_resume_complete (device, fpi_device_error_new (FP_DEVICE_ERROR_NOT_SUPPORTED));
1679+
}
1680+
break;
1681+
1682+
default:
1683+
case FPI_DEVICE_ACTION_PROBE:
1684+
case FPI_DEVICE_ACTION_OPEN:
1685+
case FPI_DEVICE_ACTION_CLOSE:
1686+
case FPI_DEVICE_ACTION_DELETE:
1687+
case FPI_DEVICE_ACTION_LIST:
1688+
case FPI_DEVICE_ACTION_CLEAR_STORAGE:
1689+
/* cannot happen as we make sure these tasks complete before suspend */
1690+
g_assert_not_reached ();
1691+
complete_suspend_resume_task (device);
1692+
break;
1693+
}
1694+
}
1695+
15951696
void
15961697
fpi_device_configure_wakeup (FpDevice *device, gboolean enabled)
15971698
{

0 commit comments

Comments
 (0)