mono-zeroconf (0.9.0-4) 03_fix-multiple-dispose.patch

Summary

 src/Mono.Zeroconf.Providers.AvahiDBus/Mono.Zeroconf.Providers.AvahiDBus/BrowseService.cs  |   10 ++--
 src/Mono.Zeroconf.Providers.AvahiDBus/Mono.Zeroconf.Providers.AvahiDBus/ServiceBrowser.cs |   25 ++++++----
 2 files changed, 23 insertions(+), 12 deletions(-)

    
download this patch

Patch contents

#! /bin/sh /usr/share/dpatch/dpatch-run
## 03_fix-multiple-dispose.patch.dpatch by  <hyperair@ubuntu.com>
## DP: Fix multiple/recursive Dispose calls

@DPATCH@
diff -urNad '--exclude=CVS' '--exclude=.svn' '--exclude=.git' '--exclude=.arch' '--exclude=.hg' '--exclude=_darcs' '--exclude=.bzr' mono-zeroconf~/src/Mono.Zeroconf.Providers.AvahiDBus/Mono.Zeroconf.Providers.AvahiDBus/BrowseService.cs mono-zeroconf/src/Mono.Zeroconf.Providers.AvahiDBus/Mono.Zeroconf.Providers.AvahiDBus/BrowseService.cs
--- mono-zeroconf~/src/Mono.Zeroconf.Providers.AvahiDBus/Mono.Zeroconf.Providers.AvahiDBus/BrowseService.cs	2011-11-07 09:24:49.000000000 +0800
+++ mono-zeroconf/src/Mono.Zeroconf.Providers.AvahiDBus/Mono.Zeroconf.Providers.AvahiDBus/BrowseService.cs	2011-11-07 11:09:53.532560321 +0800
@@ -52,19 +52,23 @@
         public void Dispose ()
         {
             lock (this) {
-                disposed = true;
-                DisposeResolver ();
+                if (!disposed) {
+                    disposed = true;
+                    DisposeResolver ();
+                }
             }
         }
         
         private void DisposeResolver ()
         {
             lock (this) {
+                IAvahiServiceResolver resolver = this.resolver;
+
                 if (resolver != null) {
+                    this.resolver = null;
                     resolver.Failure -= OnResolveFailure;
                     resolver.Found -= OnResolveFound;
                     resolver.Free ();
-                    resolver = null;
                 }
             }
         }
diff -urNad '--exclude=CVS' '--exclude=.svn' '--exclude=.git' '--exclude=.arch' '--exclude=.hg' '--exclude=_darcs' '--exclude=.bzr' mono-zeroconf~/src/Mono.Zeroconf.Providers.AvahiDBus/Mono.Zeroconf.Providers.AvahiDBus/ServiceBrowser.cs mono-zeroconf/src/Mono.Zeroconf.Providers.AvahiDBus/Mono.Zeroconf.Providers.AvahiDBus/ServiceBrowser.cs
--- mono-zeroconf~/src/Mono.Zeroconf.Providers.AvahiDBus/Mono.Zeroconf.Providers.AvahiDBus/ServiceBrowser.cs	2011-11-07 09:24:49.000000000 +0800
+++ mono-zeroconf/src/Mono.Zeroconf.Providers.AvahiDBus/Mono.Zeroconf.Providers.AvahiDBus/ServiceBrowser.cs	2011-11-07 11:09:53.532560321 +0800
@@ -45,17 +45,21 @@
         public void Dispose ()
         {
             lock (this) {
+                IAvahiServiceBrowser service_browser = this.service_browser;
                 if (service_browser != null) {
+                    this.service_browser = null;
                     service_browser.ItemNew -= OnItemNew;
                     service_browser.ItemRemove -= OnItemRemove;
                     service_browser.Free ();
                 }
-                
+
                 if (services.Count > 0) {
-                    foreach (BrowseService service in services.Values) {
+                    List<BrowseService> services_list = new List<BrowseService> (services.Values);
+                    services.Clear (); // Clear first so we no-op if we Dispose() again
+
+                    foreach (BrowseService service in services_list) {
                         service.Dispose ();
                     }
-                    services.Clear ();
                 }
             }
         }
@@ -117,10 +121,11 @@
         {
             lock (this) {
                 BrowseService service = new BrowseService (name, type, domain, @interface, protocol);
-                
-                if (services.ContainsKey (name)) {
-                    services[name].Dispose ();
+                BrowseService to_dispose;
+
+                if (services.TryGetValue (name, out to_dispose)) {
                     services[name] = service;
+                    to_dispose.Dispose ();
                 } else {
                     services.Add (name, service);
                 }
@@ -134,10 +139,12 @@
         {
             lock (this) {
                 BrowseService service = new BrowseService (name, type, domain, @interface, protocol);
-                
-                if (services.ContainsKey (name)) {
-                    services[name].Dispose ();
+                BrowseService to_dispose;
+
+                // handler may be called recursively, so remove service from services before disposing
+                if (services.TryGetValue (name, out to_dispose)) {
                     services.Remove (name);
+                    to_dispose.Dispose ();
                 }
                 
                 OnServiceRemoved (service);