Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Baulig <martin.baulig@xamarin.com>2014-06-11 20:50:47 +0400
committerMartin Baulig <martin.baulig@xamarin.com>2014-06-11 20:50:47 +0400
commit954ed3c91edeb8e22e336d7e7c9ad1a83a779f61 (patch)
tree72cb9d4c1d7bf18344748aa795a4824dcd8338b4
parent28d53d91a5da3d532f18d904772bbf3050530943 (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.cs38
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;