beagle r4612 - in trunk/beagle: Util beagled
- From: dbera svn gnome org
- To: svn-commits-list gnome org
- Subject: beagle r4612 - in trunk/beagle: Util beagled
- Date: Tue, 18 Mar 2008 03:02:29 +0000 (GMT)
Author: dbera
Date: Tue Mar 18 03:02:29 2008
New Revision: 4612
URL: http://svn.gnome.org/viewvc/beagle?rev=4612&view=rev
Log:
Fix a deadlock diagnosed using bludgeon: UnixConnectionHandler:Close was not thread-safe but could be called from an async handler which runs in a thread. Also Network.BeginRead() could throw errors itself if the connection is already terminated; catch those exceptions.
Modified:
trunk/beagle/Util/ExceptionHandlingThread.cs
trunk/beagle/beagled/Server.cs
Modified: trunk/beagle/Util/ExceptionHandlingThread.cs
==============================================================================
--- trunk/beagle/Util/ExceptionHandlingThread.cs (original)
+++ trunk/beagle/Util/ExceptionHandlingThread.cs Tue Mar 18 03:02:29 2008
@@ -60,8 +60,8 @@
} catch (ThreadAbortException e) {
Logger.Log.Debug ("Thread aborted: {0}\n{1}\n", this.thread.Name, e.StackTrace);
} catch (Exception e) {
- Logger.Log.Warn (e, "Exception caught while executing {0}:{1}",
- this.method.Target, this.method.Method);
+ Logger.Log.Warn (e, "Exception caught in {2} while executing {0}:{1}",
+ this.method.Target, this.method.Method, this.thread.Name);
}
lock (live_threads)
Modified: trunk/beagle/beagled/Server.cs
==============================================================================
--- trunk/beagle/beagled/Server.cs (original)
+++ trunk/beagle/beagled/Server.cs Tue Mar 18 03:02:29 2008
@@ -409,6 +409,8 @@
Shutdown.WorkerFinished (network_data);
}
+ private bool closed = false;
+
public override void Close ()
{
CancelIfBlocking ();
@@ -417,17 +419,24 @@
// grab the lock here and close the underlying
// UnixClient, or else we'd deadlock between here and
// the Read() in HandleConnection()
+
+ // Do this in a lock since Close() should be thread-safe (can be called from AsyncCallback handler)
lock (this.client_lock) {
+ if (closed)
+ return;
+
if (this.client != null) {
this.client.Close ();
this.client = null;
}
- }
- if (this.executor != null) {
- this.executor.Cleanup ();
- this.executor.AsyncResponseEvent -= OnAsyncResponse;
- this.executor = null;
+ if (this.executor != null) {
+ this.executor.Cleanup ();
+ this.executor.AsyncResponseEvent -= OnAsyncResponse;
+ this.executor = null;
+ }
+
+ closed = true;
}
Server.RunGC ();
@@ -439,8 +448,10 @@
try {
bytes_read = this.client.GetStream ().EndRead (ar);
- } catch (SocketException) {
- } catch (IOException) { }
+ } catch (IOException e) {
+ if (! (e.InnerException is SocketException))
+ throw e;
+ } catch (ObjectDisposedException) { }
if (bytes_read == 0)
Close ();
@@ -455,8 +466,26 @@
return;
}
- this.client.GetStream ().BeginRead (new byte[1024], 0, 1024,
- new AsyncCallback (WatchCallback), null);
+ try {
+ this.client.GetStream ().BeginRead (new byte[1024], 0, 1024,
+ new AsyncCallback (WatchCallback), null);
+ } catch (ObjectDisposedException) {
+ Log.Debug ("Network stream closed; closing connection at this end");
+ this.Close ();
+ return;
+ } catch (IOException e) {
+ if (e.InnerException is SocketException) {
+ Log.Debug (e.InnerException, "Socket exception while setting up watch");
+ this.Close ();
+ return;
+ } else
+ throw e;
+ } catch (System.ArgumentException e) {
+ // https://bugzilla.novell.com/show_bug.cgi?id=371923
+ Log.Debug (e, "Possibly socket is already closed");
+ this.Close ();
+ return;
+ }
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]