Imported Upstream version 5.16.0.100

Former-commit-id: 38faa55fb9669e35e7d8448b15c25dc447f25767
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2018-08-07 15:19:03 +00:00
parent 0a9828183b
commit 7d7f676260
4419 changed files with 170950 additions and 90273 deletions

View File

@ -36,8 +36,8 @@ namespace System.Net
{
class ServicePointScheduler
{
public ServicePoint ServicePoint {
get;
ServicePoint ServicePoint {
get; set;
}
public int MaxIdleTime {
@ -80,12 +80,6 @@ namespace System.Net
idleSince = DateTime.UtcNow;
}
[Conditional ("MONO_WEB_DEBUG")]
void Debug (string message, params object[] args)
{
WebConnection.Debug ($"SPS({ID}): {string.Format (message, args)}");
}
[Conditional ("MONO_WEB_DEBUG")]
void Debug (string message)
{
@ -124,15 +118,14 @@ namespace System.Net
public void Run ()
{
lock (ServicePoint) {
if (Interlocked.CompareExchange (ref running, 1, 0) == 0)
StartScheduler ();
Debug ($"RUN");
if (Interlocked.CompareExchange (ref running, 1, 0) == 0)
Task.Run (() => RunScheduler ());
schedulerEvent.Set ();
}
schedulerEvent.Set ();
}
async void StartScheduler ()
async Task RunScheduler ()
{
idleSince = DateTime.UtcNow + TimeSpan.FromDays (3650);
@ -143,36 +136,47 @@ namespace System.Net
ValueTuple<ConnectionGroup, WebOperation>[] operationArray;
ValueTuple<ConnectionGroup, WebConnection, Task>[] idleArray;
var taskList = new List<Task> ();
Task<bool> schedulerTask;
bool finalCleanup = false;
lock (ServicePoint) {
Cleanup ();
if (groups == null && defaultGroup.IsEmpty () && operations.Count == 0 && idleConnections.Count == 0) {
Debug ($"MAIN LOOP DONE");
running = 0;
idleSince = DateTime.UtcNow;
schedulerEvent.Reset ();
return;
}
operationArray = new ValueTuple<ConnectionGroup, WebOperation>[operations.Count];
operations.CopyTo (operationArray, 0);
idleArray = new ValueTuple<ConnectionGroup, WebConnection, Task>[idleConnections.Count];
idleConnections.CopyTo (idleArray, 0);
taskList.Add (schedulerEvent.WaitAsync (maxIdleTime));
foreach (var item in operationArray)
taskList.Add (item.Item2.Finished.Task);
foreach (var item in idleArray)
taskList.Add (item.Item3);
schedulerTask = schedulerEvent.WaitAsync (maxIdleTime);
taskList.Add (schedulerTask);
if (groups == null && defaultGroup.IsEmpty () && operations.Count == 0 && idleConnections.Count == 0) {
Debug ($"MAIN LOOP DONE");
idleSince = DateTime.UtcNow;
finalCleanup = true;
} else {
foreach (var item in operationArray)
taskList.Add (item.Item2.Finished.Task);
foreach (var item in idleArray)
taskList.Add (item.Item3);
}
}
Debug ($"MAIN LOOP #1: operations={operationArray.Length} idle={idleArray.Length}");
Debug ($"MAIN LOOP #1: operations={operationArray.Length} idle={idleArray.Length} maxIdleTime={maxIdleTime} finalCleanup={finalCleanup}");
var ret = await Task.WhenAny (taskList).ConfigureAwait (false);
lock (ServicePoint) {
bool runMaster = false;
if (ret == taskList[0])
if (finalCleanup) {
if (schedulerTask.Result)
runMaster = true;
else {
FinalCleanup ();
return;
}
} else if (ret == taskList[0]) {
runMaster = true;
}
/*
* We discard the `taskList` at this point as it is only used to wake us up.
@ -252,7 +256,7 @@ namespace System.Net
repeat = SchedulerIteration (defaultGroup);
Debug ($"ITERATION #1: {repeat} {groups != null}");
Debug ($"ITERATION #1: repeat={repeat} groups={groups?.Count}");
if (groups != null) {
foreach (var group in groups) {
@ -261,7 +265,7 @@ namespace System.Net
}
}
Debug ($"ITERATION #3: {repeat}");
Debug ($"ITERATION #3: repeat={repeat}");
} while (repeat);
}
@ -378,6 +382,20 @@ namespace System.Net
}
}
void FinalCleanup ()
{
Debug ($"FINAL CLEANUP");
groups = null;
operations = null;
idleConnections = null;
defaultGroup = null;
ServicePoint.FreeServicePoint ();
ServicePointManager.RemoveServicePoint (ServicePoint);
ServicePoint = null;
}
public void SendRequest (WebOperation operation, string groupName)
{
lock (ServicePoint) {
@ -391,25 +409,23 @@ namespace System.Net
public bool CloseConnectionGroup (string groupName)
{
lock (ServicePoint) {
ConnectionGroup group;
if (string.IsNullOrEmpty (groupName))
group = defaultGroup;
else if (groups == null || !groups.TryGetValue (groupName, out group))
return false;
ConnectionGroup group;
if (string.IsNullOrEmpty (groupName))
group = defaultGroup;
else if (groups == null || !groups.TryGetValue (groupName, out group))
return false;
Debug ($"CLOSE CONNECTION GROUP: group={group.ID}");
Debug ($"CLOSE CONNECTION GROUP: group={group.ID}");
if (group != defaultGroup) {
groups.Remove (groupName);
if (groups.Count == 0)
groups = null;
}
group.Close ();
Run ();
return true;
if (group != defaultGroup) {
groups.Remove (groupName);
if (groups.Count == 0)
groups = null;
}
group.Close ();
Run ();
return true;
}
ConnectionGroup GetConnectionGroup (string name)