diff options
author | Martin Baulig <martin.baulig@xamarin.com> | 2014-06-11 20:50:47 +0400 |
---|---|---|
committer | Martin Baulig <martin.baulig@xamarin.com> | 2014-06-11 20:50:47 +0400 |
commit | 954ed3c91edeb8e22e336d7e7c9ad1a83a779f61 (patch) | |
tree | 72cb9d4c1d7bf18344748aa795a4824dcd8338b4 | |
parent | 28d53d91a5da3d532f18d904772bbf3050530943 (diff) |
[Http]: Fix a potential race condition in the WebConnectionGroup's connection list.mono-3.4.0-branch
Remove the "ConnectionState" from the connection list before closing the connection,
this should avoid ServicePoint.SendRequest() ever crashing with a NullReferenceException
due to getting a null return value from WebConnectionGroup.GetConnection().
-rw-r--r-- | mcs/class/System/System.Net/WebConnectionGroup.cs | 38 |
1 files changed, 20 insertions, 18 deletions
diff --git a/mcs/class/System/System.Net/WebConnectionGroup.cs b/mcs/class/System/System.Net/WebConnectionGroup.cs index 0348aeebe42..5e142154f91 100644 --- a/mcs/class/System/System.Net/WebConnectionGroup.cs +++ b/mcs/class/System/System.Net/WebConnectionGroup.cs @@ -70,14 +70,16 @@ namespace System.Net //TODO: abort requests or wait for them to finish lock (sPoint) { closing = true; - foreach (var cnc in connections) { - if (cnc.Connection == null) - continue; - cnc.Connection.Close (false); - cnc.Connection = null; + var iter = connections.First; + while (iter != null) { + var cnc = iter.Value.Connection; + var node = iter; + iter = iter.Next; + + connections.Remove (node); + cnc.Close (false); OnConnectionClosed (); } - connections.Clear (); } } @@ -120,7 +122,7 @@ namespace System.Net ConnectionState FindIdleConnection () { foreach (var cnc in connections) { - if (cnc.Busy || cnc.Connection == null) + if (cnc.Busy) continue; connections.Remove (cnc); @@ -140,7 +142,7 @@ namespace System.Net return cnc.Connection; } - if (sPoint.ConnectionLimit > connections.Count) { + if (sPoint.ConnectionLimit > connections.Count || connections.Count == 0) { created = true; cnc = new ConnectionState (this); connections.AddFirst (cnc); @@ -177,14 +179,11 @@ namespace System.Net } int count = 0; - for (var node = connections.First; node != null; node = node.Next) { - var cnc = node.Value; - - if (cnc.Connection == null) { - connections.Remove (node); - OnConnectionClosed (); - continue; - } + var iter = connections.First; + while (iter != null) { + var cnc = iter.Value; + var node = iter; + iter = iter.Next; ++count; if (cnc.Busy) @@ -205,7 +204,7 @@ namespace System.Net if (connectionsToClose == null) connectionsToClose = new List<WebConnection> (); connectionsToClose.Add (cnc.Connection); - cnc.Connection = null; + connections.Remove (node); } recycled = connections.Count == 0; @@ -224,7 +223,10 @@ namespace System.Net } class ConnectionState : IWebConnectionState { - public WebConnection Connection; + public WebConnection Connection { + get; + private set; + } public WebConnectionGroup Group { get; |