No "show-unmount-progress" signal sent when unmount succeeds during "show-processes" dialog
Mount a USB drive. Open a file on it, and keep it open. Try unmount/eject it. The "show-processes" dialog will be brought up, showing the process with the open file, with "Cancel" and "Eject anyway" buttons, while gvfs keeps trying to unmount in the background. If neither button is clicked, and the open file is closed, the dialog is closed, but the "show-unmount-progress" signal (with its "... can be safely unplugged" message) isn't emitted, despite the unmount succeeding.
Why? The "show-unmount-progress" signal is emitted in gvfs_udisks2_unmount_notify_stop()
, below:
void
gvfs_udisks2_unmount_notify_stop (GMountOperation *op,
gboolean unmount_failed)
{
gchar *message, *name;
UnmountNotifyData *data = g_object_get_data (G_OBJECT (op), "x-udisks2-notify-data");
if (data == NULL)
return;
unmount_notify_stop_timer (data);
if (data->op_aborted || unmount_failed)
return;
name = unmount_notify_get_name (data);
if (data->mount)
message = g_strdup_printf (_("%s unmounted\nFilesystem has been disconnected."), name);
else
message = g_strdup_printf (_("%s can be safely unplugged\nDevice can be removed."), name);
g_signal_emit_by_name (data->op, "show-unmount-progress",
message, 0, 0);
g_free (message);
g_free (name);
}
So the signal is not emitted if data->op_aborted
is true, or unmount_failed
is true. What values do those variables have under various scenarios?
Scenario | data->op_aborted | unmount_failed |
---|---|---|
(1) Immediately successful unmount | 0 | 0 |
(2) "show-processes" dialog, "Cancel" clicked | 1 | 1 |
(3) "show-processes" dialog, "Eject anyway" clicked | 0 | 0 |
(4) "show-processes" dialog, open files manually closed, unmounting then succeeds | 1 | 0 |
(5) "show-processes" dialog, drive pulled out (too early) | 0 | 1 |
So in scenario (4) the signal isn't emitted because data->op_aborted
is true. This was set in unmount_notify_op_aborted()
because the "aborted" signal was emitted. The "aborted" signal is emitted by unmount_data_free()
just to make the dialog go away, not because there is an error:
if (data->mount_op_reply_handler_id > 0)
{
/* make the operation dialog go away */
g_signal_emit_by_name (data->mount_operation, "aborted");
g_signal_handler_disconnect (data->mount_operation, data->mount_op_reply_handler_id);
}
If we look at the table, we see that "show-unmount-progress" should be sent in every case that unmount_failed
is false, regardless of the value of data->op_aborted
. Thus the correct fix seems to be to make gvfs_udisks2_unmount_notify_stop()
ignore the value of data->op_aborted
:
diff --git a/monitor/udisks2/gvfsudisks2utils.c b/monitor/udisks2/gvfsudisks2utils.c
index df56962b..caef8357 100644
--- a/monitor/udisks2/gvfsudisks2utils.c
+++ b/monitor/udisks2/gvfsudisks2utils.c
@@ -780,7 +780,7 @@ gvfs_udisks2_unmount_notify_stop (GMountOperation *op,
unmount_notify_stop_timer (data);
- if (data->op_aborted || unmount_failed)
+ if (unmount_failed)
return;
name = unmount_notify_get_name (data);