[gvfs] afc: Fix force unmount of devices



commit 32adf492a9a2ab5cef953cf2dfd9f00c25c785e7
Author: Christophe Fergeau <cfergeau redhat com>
Date:   Mon Mar 9 17:48:24 2015 +0100

    afc: Fix force unmount of devices
    
    When unplugging an afc device without unmounting it first, the
    corresponding gvfsd-afc process does not go away in spite of the
    exit(1) workaround added for bgo#708288.
    
    This happens because idevice_event_unsubscribe() in called from the
    thread where the _idevice_event_cb() runs in. libimobiledevice (through
    libusbmuxd) creates a thread to watch for device events, and calls the
    idevice_event_cb_t from that thread. idevice_event_unsubscribe() then
    forcfully kills that thread (see usbmuxd_unsubscribe() in libusbmuxd),
    so exit(1) code after the call to idevice_event_unsubscribe() never gets
    a chance to run.
    
    Moving the call to idevice_event_unsubscribe() and the
    g_vfs_backend_force_unmount() call to run in the main loop through
    g_idle_add() avoids this issue, and allows the code handling force
    unmounts to run as expected.
    
    Fixes: https://bugzilla.gnome.org/show_bug.cgi?id=708288

 daemon/gvfsbackendafc.c |   24 +++++++++++++++++-------
 1 files changed, 17 insertions(+), 7 deletions(-)
---
diff --git a/daemon/gvfsbackendafc.c b/daemon/gvfsbackendafc.c
index bb9a38e..22bab16 100644
--- a/daemon/gvfsbackendafc.c
+++ b/daemon/gvfsbackendafc.c
@@ -342,6 +342,20 @@ app_info_free (AppInfo *info)
   g_free (info);
 }
 
+static gboolean
+force_umount_idle (gpointer user_data)
+{
+  GVfsBackendAfc *afc_backend = G_VFS_BACKEND_AFC (user_data);
+
+  g_vfs_backend_afc_close_connection (afc_backend);
+
+  idevice_event_unsubscribe ();
+
+  g_vfs_backend_force_unmount (G_VFS_BACKEND(afc_backend));
+
+  return G_SOURCE_REMOVE;
+}
+
 static void
 _idevice_event_cb (const idevice_event_t *event, void *user_data)
 {
@@ -358,13 +372,9 @@ _idevice_event_cb (const idevice_event_t *event, void *user_data)
 
   g_print ("Shutting down AFC backend for device uuid %s\n", afc_backend->uuid);
 
-  g_vfs_backend_afc_close_connection (afc_backend);
-
-  idevice_event_unsubscribe ();
-
-  /* TODO: need a cleaner way to force unmount ourselves:
-   * https://bugzilla.gnome.org/show_bug.cgi?id=708288 */
-  exit (1);
+  /* idevice_event_unsubscribe() will terminate the thread _idevice_event_cb
+   * is running in, so we need to call back into our main loop */
+  g_idle_add(force_umount_idle, afc_backend);
 }
 
 static gboolean


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]