summaryrefslogtreecommitdiff
path: root/client/gvfsfusedaemon.c
diff options
context:
space:
mode:
authorOndrej Holy <oholy@redhat.com>2016-03-10 11:51:19 +0100
committerOndrej Holy <oholy@redhat.com>2016-03-11 08:27:08 +0100
commit618c9cbb8621ef0e801cea609a5eaafff88af378 (patch)
tree640c47f85046c8bab6e1d609db74acb8d65e29f5 /client/gvfsfusedaemon.c
parente941bbd3124f04ad10f85b42cc03cb4aaf7ddf81 (diff)
downloadgvfs-618c9cbb8621ef0e801cea609a5eaafff88af378.tar.gz
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
Diffstat (limited to 'client/gvfsfusedaemon.c')
-rw-r--r--client/gvfsfusedaemon.c18
1 files changed, 9 insertions, 9 deletions
diff --git a/client/gvfsfusedaemon.c b/client/gvfsfusedaemon.c
index f67c7c05..b99f7c09 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 =