[gvfs] MTP: Fix race between on_uevent and do_unmount.
- From: Philip Langdale <philipl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gvfs] MTP: Fix race between on_uevent and do_unmount.
- Date: Wed, 23 Jan 2013 17:13:57 +0000 (UTC)
commit 2ad82f2751b4a13dbcf8e7373a386019982bb43b
Author: Philip Langdale <philipl overt org>
Date: Wed Jan 23 09:07:22 2013 -0800
MTP: Fix race between on_uevent and do_unmount.
I've never seen this happen personally, but an Ubuntu bug reported
that on_uevent fired after the gudev client had been finalized, so
it must be possible to race between an explicit unmount and
physically unplugging a device. I made a brief attempt to reproduce
this but couldn't.
In any case, it's easy enough to protect against by taking a few
measures:
1) Explicitly disconnect the signal handler before unref'ing the
gudev client.
2) Use g_signal_connect_object to keep the backend alive enough
for on_uevent to complete.
3) NULL out the dev_path so that if we end up in on_uevent after
do_unmount has cleared the dev_path, the compare will fail
gracefully.
daemon/gvfsbackendmtp.c | 8 ++++++--
daemon/gvfsbackendmtp.h | 1 +
2 files changed, 7 insertions(+), 2 deletions(-)
---
diff --git a/daemon/gvfsbackendmtp.c b/daemon/gvfsbackendmtp.c
index 121115a..a39e4d1 100644
--- a/daemon/gvfsbackendmtp.c
+++ b/daemon/gvfsbackendmtp.c
@@ -449,7 +449,9 @@ do_mount (GVfsBackend *backend,
}
op_backend->dev_path = dev_path;
- g_signal_connect (op_backend->gudev_client, "uevent", G_CALLBACK (on_uevent), op_backend);
+ op_backend->on_uevent_id =
+ g_signal_connect_object (op_backend->gudev_client, "uevent",
+ G_CALLBACK (on_uevent), op_backend, 0);
LIBMTP_Init ();
@@ -497,8 +499,10 @@ do_unmount (GVfsBackend *backend, GVfsJobUnmount *job,
g_atomic_int_set (&op_backend->unmount_started, TRUE);
g_source_remove (op_backend->hb_id);
+ g_signal_handler_disconnect (op_backend->gudev_client,
+ op_backend->on_uevent_id);
g_object_unref (op_backend->gudev_client);
- g_free (op_backend->dev_path);
+ g_clear_pointer (&op_backend->dev_path, g_free);
LIBMTP_Release_Device (op_backend->device);
g_mutex_unlock (&op_backend->mutex);
diff --git a/daemon/gvfsbackendmtp.h b/daemon/gvfsbackendmtp.h
index 9dbaa0c..4137b65 100644
--- a/daemon/gvfsbackendmtp.h
+++ b/daemon/gvfsbackendmtp.h
@@ -47,6 +47,7 @@ struct _GVfsBackendMtp
#ifdef HAVE_GUDEV
GUdevClient *gudev_client;
+ gulong on_uevent_id;
#endif
GMutex mutex;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]