[gvfs] fuse: Avoid crashes when exiting



commit 618c9cbb8621ef0e801cea609a5eaafff88af378
Author: Ondrej Holy <oholy redhat com>
Date:   Thu Mar 10 11:51:19 2016 +0100

    fuse: Avoid crashes when exiting
    
    There may be a race when exiting between a fuse main loop and
    a subthread's main loop. Therefore call g_main_loop_quit always
    from vfs_destroy on the main thread and wait there for a termination
    of the subthread to avoid the race.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=762250

 client/gvfsfusedaemon.c |   18 +++++++++---------
 1 files changed, 9 insertions(+), 9 deletions(-)
---
diff --git a/client/gvfsfusedaemon.c b/client/gvfsfusedaemon.c
index f67c7c0..b99f7c0 100644
--- a/client/gvfsfusedaemon.c
+++ b/client/gvfsfusedaemon.c
@@ -2347,15 +2347,9 @@ subthread_main (gpointer data)
   g_signal_handlers_disconnect_by_func (volume_monitor, mount_tracker_mounted_cb, NULL);
   g_signal_handlers_disconnect_by_func (volume_monitor, mount_tracker_unmounted_cb, NULL);
 
-  g_main_loop_unref (subthread_main_loop);
-  subthread_main_loop = NULL;
-
   g_object_unref (volume_monitor);
   volume_monitor = NULL;
 
-  /* Tell the main thread to unmount. Using kill() is necessary according to FUSE maintainers. */
-  kill (getpid (), SIGHUP);
-
   return NULL;
 }
 
@@ -2365,7 +2359,7 @@ name_vanished_handler (GDBusConnection *connection,
                        gpointer user_data)
 {
   /* The daemon died, unmount */
-  g_main_loop_quit (subthread_main_loop);
+  kill (getpid (), SIGHUP);
 }
 
 static void
@@ -2375,7 +2369,7 @@ dbus_connection_closed (GDBusConnection *connection,
                         gpointer user_data)
 {
   /* Session bus died, unmount */
-  g_main_loop_quit (subthread_main_loop);
+  kill (getpid (), SIGHUP);
 }
 
 static void
@@ -2479,9 +2473,15 @@ vfs_destroy (gpointer param)
     g_bus_unwatch_name (daemon_name_watcher);
   g_clear_object (&dbus_conn);
   
-  mount_list_free ();
   if (subthread_main_loop != NULL) 
     g_main_loop_quit (subthread_main_loop);
+
+  if (subthread)
+    g_thread_join (subthread);
+
+  g_clear_pointer (&subthread_main_loop, g_main_loop_unref);
+
+  mount_list_free ();
 }
 
 static struct fuse_operations vfs_oper =


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