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 21:02:02 +0400 |
commit | fc9593eb8910ba6efe65e94cced22b4242c18791 (patch) | |
tree | 6120d933e85198778fc706ab02e9ad9929138427 | |
parent | a7157b51bb4d0b92ecb1d50d54be1f476f3aeff0 (diff) |
[Http]: Fix a potential race condition in the WebConnectionGroup's connection list.monotouch-7.2.1-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; |