summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorOndrej Holy <oholy@redhat.com>2020-01-27 14:02:36 +0100
committerOndrej Holy <oholy@redhat.com>2020-01-27 13:33:49 +0000
commitc8f8f345a0c88e68dd21f6b548ab1cfba56732e9 (patch)
tree9014e47745824532679071a111255e28fbebc972 /common
parent293bd87a35cf4b9cda096f38cd5ecebd2df7a7e1 (diff)
downloadgvfs-c8f8f345a0c88e68dd21f6b548ab1cfba56732e9.tar.gz
dnssd: Prevent crashes after releasing resolver
The following error often happens when mounting dav+sd share (e.g. created over gnome-user-media) and the mount operation fails for some reason: dbus[47482]: arguments to dbus_connection_unref() were incorrect, assertion "connection->generation == _dbus_current_generation" failed in file ../../dbus/dbus-connection.c line 2823. This is normally a bug in some application using the D-Bus library. This is because avahi is not thread-safe and our resolver doesn't use mutexes. But it seems to me that mutexes are not necessarily needed if everything would work as expected. Unfortunately, changes made by commit 3384af8 causes that start_avahi_resolver is being called multiple times by mistake, which also calls avahi_service_resolver_new multiple times. Consequently, it may crash when resolver is beeing freed too early as there might still be unexpected pending operations using avahi client. Fixes: GNOME/gvfs#449
Diffstat (limited to 'common')
-rw-r--r--common/gvfsdnssdresolver.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/common/gvfsdnssdresolver.c b/common/gvfsdnssdresolver.c
index 7aa2cfcb..b7f0cd3f 100644
--- a/common/gvfsdnssdresolver.c
+++ b/common/gvfsdnssdresolver.c
@@ -85,6 +85,7 @@ struct _GVfsDnsSdResolver
char **txt_records;
AvahiServiceResolver *avahi_resolver;
+ guint start_avahi_resolver_id;
};
@@ -245,6 +246,7 @@ start_avahi_resolver (gpointer user_data)
resolver);
out:
+ resolver->start_avahi_resolver_id = 0;
g_object_unref (resolver);
return FALSE;
}
@@ -252,10 +254,10 @@ out:
static void
ensure_avahi_resolver (GVfsDnsSdResolver *resolver)
{
- if (resolver->avahi_resolver != NULL)
+ if (resolver->avahi_resolver != NULL || resolver->start_avahi_resolver_id != 0)
return;
- g_idle_add (start_avahi_resolver, g_object_ref (resolver));
+ resolver->start_avahi_resolver_id = g_idle_add (start_avahi_resolver, g_object_ref (resolver));
}
static void
@@ -382,6 +384,8 @@ g_vfs_dns_sd_resolver_finalize (GObject *object)
if (resolver->avahi_resolver != NULL)
avahi_service_resolver_free (resolver->avahi_resolver);
+ if (resolver->start_avahi_resolver_id != 0)
+ g_source_remove (resolver->start_avahi_resolver_id);
resolvers = g_list_remove (resolvers, resolver);