[gvfs] Avoid deadlock when pulling resolved dns-sd record from cache



commit 8b97c4a5a7e5a0a16593a405ffa849835f645072
Author: Tomas Bzatek <tbzatek redhat com>
Date:   Tue Aug 18 17:23:26 2009 +0200

    Avoid deadlock when pulling resolved dns-sd record from cache
    
    When the host has already been resolved and is present in cache,
    it's returned immediately. But we always started a mainloop
    resulting in endless waiting for an event which had been received
    before that. This applies for the sync call.
    
    This is just a workaround, the sync code should be ported over avahi.
    See bug 555436 (comments 30-32) for details.

 common/gvfsdnssdresolver.c |   13 +++++++++++--
 1 files changed, 11 insertions(+), 2 deletions(-)
---
diff --git a/common/gvfsdnssdresolver.c b/common/gvfsdnssdresolver.c
index 7794042..1bb92e9 100644
--- a/common/gvfsdnssdresolver.c
+++ b/common/gvfsdnssdresolver.c
@@ -23,6 +23,7 @@
 /*
  * TODO: - locking
  *       - cancellation
+ *       - get rid of g_main_loop (bug 555436#c32)
  */
 
 #include <config.h>
@@ -1248,15 +1249,23 @@ g_vfs_dns_sd_resolver_resolve_sync (GVfsDnsSdResolver  *resolver,
 
   g_return_val_if_fail (G_VFS_IS_DNS_SD_RESOLVER (resolver), FALSE);
 
+  /* TODO: get rid of this nested mainloop, port to avahi mainloop instead  */
+  /*       see http://bugzilla.gnome.org/show_bug.cgi?id=555436#c32 */
+
   data = g_new0 (ResolveDataSync, 1);
-  data->loop = g_main_loop_new (NULL, FALSE);
+  /* mark the main loop as running to have an indication
+     whether g_main_loop_quit() was called before g_main_loop_run() */
+  data->loop = g_main_loop_new (NULL, TRUE);
 
   g_vfs_dns_sd_resolver_resolve (resolver,
                                  cancellable,
                                  (GAsyncReadyCallback) resolve_sync_cb,
                                  data);
 
-  g_main_loop_run (data->loop);
+  /* start main loop only if wasn't quit before
+     (i.e. in case when pulling record from cache) */
+  if (g_main_loop_is_running (data->loop))
+    g_main_loop_run (data->loop);
 
   ret = data->ret;
   if (data->error != NULL)



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