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:
authorjustremotephone <justremotephone@gmail.com>2019-03-06 03:07:29 +0300
committerAlexander Köplinger <alex.koeplinger@outlook.com>2019-03-06 03:07:29 +0300
commiteb3f7312bd4da3e6ca1e072c06fcb3f1338ad974 (patch)
tree13bc472ae77512daa74af3512c35dd20d36094b0 /mcs/class/System.ServiceModel
parent24c637dd2651bb1ea137e872291dc5163dedf50d (diff)
[System.ServiceModel] Fix a race condition in HttpRequestChannel. (#13304)
Concurrent request completions could cause following exception: ``` FATAL UNHANDLED EXCEPTION: System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index at System.Collections.Generic.List`1[T].RemoveAt (System.Int32 index) [0x00009] in <4a8a0eaa024f41829d3435c07e5c7edb>:0 at System.Collections.Generic.List`1[T].Remove (T item) [0x0000c] in <4a8a0eaa024f41829d3435c07e5c7edb>:0 at System.ServiceModel.Channels.HttpRequestChannel+HttpChannelRequestAsyncResult.Cleanup () [0x00011] in <28c4695205ef47378f5370502b066592>:0 at System.ServiceModel.Channels.HttpRequestChannel+HttpChannelRequestAsyncResult.set_IsCompleted (System.Boolean value) [0x00034] in <28c4695205ef47378f5370502b066592>:0 at System.ServiceModel.Channels.HttpRequestChannel+HttpChannelRequestAsyncResult.Complete (System.Exception ex) [0x0001a] in <28c4695205ef47378f5370502b066592>:0 at System.ServiceModel.Channels.HttpRequestChannel+<>c__DisplayClass7_1.<BeginProcessRequest>b__0 (System.IAsyncResult r) [0x000bd] in <28c4695205ef47378f5370502b066592>:0 This stack was captured after some changes in AwaitTaskContinuation.RunOrScheduleAction. Unfortunately the current implementation of AwaitTaskContinuation.RunOrScheduleAction re-throws the above exception with a wrong stack: at System.Threading.Tasks.AwaitTaskContinuation.RunOrScheduleAction (System.Action action, System.Boolean allowInlining, System.Threading.Tasks.Task& currentTask) [0x00023] in <4a8a0eaa024f41829d3435c07e5c7edb>:0 at System.Threading.Tasks.Task.FinishContinuations () [0x00052] in <4a8a0eaa024f41829d3435c07e5c7edb>:0 at System.Threading.Tasks.Task.FinishStageThree () [0x0003c] in <4a8a0eaa024f41829d3435c07e5c7edb>:0 at System.Threading.Tasks.Task.FinishStageTwo () [0x000a1] in <4a8a0eaa024f41829d3435c07e5c7edb>:0 at System.Threading.Tasks.Task.Finish (System.Boolean bUserDelegateExecuted) [0x00003] in <4a8a0eaa024f41829d3435c07e5c7edb>:0 at System.Threading.Tasks.Task.TrySetException (System.Object exceptionObject) [0x00023] in <4a8a0eaa024f41829d3435c07e5c7edb>:0 at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1[TResult].SetException (System.Exception exception) [0x00029] in <4a8a0eaa024f41829d3435c07e5c7edb>:0 at System.Net.HttpWebRequest+<RunWithTimeoutWorker>d__241`1[T].MoveNext () [0x000e0] in <3e9b3e26c4694baab3f689687ad40612>:0 at System.Runtime.CompilerServices.AsyncMethodBuilderCore+MoveNextRunner.InvokeMoveNext (System.Object stateMachine) [0x00000] in <4a8a0eaa024f41829d3435c07e5c7edb>:0 at System.Threading.ExecutionContext.RunInternal (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, System.Boolean preserveSyncCtx) [0x00071] in <4a8a0eaa024f41829d3435c07e5c7edb>:0 at System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, System.Boolean preserveSyncCtx) [0x00000] in <4a8a0eaa024f41829d3435c07e5c7edb>:0 at System.Runtime.CompilerServices.AsyncMethodBuilderCore+MoveNextRunner.Run () [0x00024] in <4a8a0eaa024f41829d3435c07e5c7edb>:0 at System.Threading.Tasks.AwaitTaskContinuation.RunOrScheduleAction (System.Action action, System.Boolean allowInlining, System.Threading.Tasks.Task& currentTask) [0x00023] in <4a8a0eaa024f41829d3435c07e5c7edb>:0 at System.Threading.Tasks.Task.FinishContinuations () [0x00052] in <4a8a0eaa024f41829d3435c07e5c7edb>:0 at System.Threading.Tasks.Task.FinishStageThree () [0x0003c] in <4a8a0eaa024f41829d3435c07e5c7edb>:0 at System.Threading.Tasks.Task`1[TResult].TrySetResult (TResult result) [0x0004f] in <4a8a0eaa024f41829d3435c07e5c7edb>:0 at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1[TResult].SetResult (TResult result) [0x0003d] in <4a8a0eaa024f41829d3435c07e5c7edb>:0 at System.Net.ServicePointScheduler+<WaitAsync>d__45.MoveNext () [0x000f7] in <3e9b3e26c4694baab3f689687ad40612>:0 at System.Runtime.CompilerServices.AsyncMethodBuilderCore+MoveNextRunner.InvokeMoveNext (System.Object stateMachine) [0x00000] in <4a8a0 ``` On an Android Xamarin installation this causes an app crash. Since no user code is active the exception cannot be caught.
Diffstat (limited to 'mcs/class/System.ServiceModel')
-rw-r--r--mcs/class/System.ServiceModel/System.ServiceModel.Channels/HttpRequestChannel.cs30
1 files changed, 25 insertions, 5 deletions
diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/HttpRequestChannel.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/HttpRequestChannel.cs
index 4e4d73f9fb1..c5a96fe3314 100644
--- a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/HttpRequestChannel.cs
+++ b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/HttpRequestChannel.cs
@@ -41,7 +41,8 @@ namespace System.ServiceModel.Channels
{
HttpChannelFactory<IRequestChannel> source;
- List<WebRequest> web_requests = new List<WebRequest> ();
+ object locker = new object();
+ List<WebRequest> web_requests = new List<WebRequest> (); //synced by locker
// Constructor
@@ -86,7 +87,12 @@ namespace System.ServiceModel.Channels
}
var web_request = (HttpWebRequest) HttpWebRequest.Create (destination);
- web_requests.Add (web_request);
+
+ lock (locker)
+ {
+ web_requests.Add (web_request);
+ }
+
result.WebRequest = web_request;
web_request.Method = "POST";
web_request.ContentType = Encoder.ContentType;
@@ -350,9 +356,20 @@ namespace System.ServiceModel.Channels
protected override void OnAbort ()
{
- foreach (var web_request in web_requests.ToArray ())
+ WebRequest[] current_web_requests;
+
+ lock (locker)
+ {
+ current_web_requests = web_requests.ToArray();
+ }
+
+ foreach (var web_request in current_web_requests)
web_request.Abort ();
- web_requests.Clear ();
+
+ lock(locker)
+ {
+ web_requests.Clear ();
+ }
}
// Close
@@ -497,7 +514,10 @@ namespace System.ServiceModel.Channels
void Cleanup ()
{
- owner.web_requests.Remove (WebRequest);
+ lock (owner.locker)
+ {
+ owner.web_requests.Remove (WebRequest);
+ }
}
}
}