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:
authorAlexander Köplinger <alex.koeplinger@outlook.com>2019-03-18 16:39:54 +0300
committerAlexander Köplinger <alex.koeplinger@outlook.com>2019-03-18 16:39:54 +0300
commit5521ad349fdfa7e32ba3aa243a08127ece87810e (patch)
treecd177f3ce2d4823880527e07a46bf3737429446b /mcs/class/System.Net.Http
parente0326df7c6ff746fe8ab1105cced92f8ba8cb87e (diff)
[System.Net.Http] Port https://github.com/xamarin/xamarin-macios/pull/5769 to mono
Diffstat (limited to 'mcs/class/System.Net.Http')
-rw-r--r--mcs/class/System.Net.Http/NSUrlSessionHandler.cs45
1 files changed, 41 insertions, 4 deletions
diff --git a/mcs/class/System.Net.Http/NSUrlSessionHandler.cs b/mcs/class/System.Net.Http/NSUrlSessionHandler.cs
index e48129c0877..17835da99f6 100644
--- a/mcs/class/System.Net.Http/NSUrlSessionHandler.cs
+++ b/mcs/class/System.Net.Http/NSUrlSessionHandler.cs
@@ -204,7 +204,12 @@ namespace Foundation {
void RemoveInflightData (NSUrlSessionTask task, bool cancel = true)
{
lock (inflightRequestsLock) {
- inflightRequests.Remove (task);
+ if (inflightRequests.TryGetValue (task, out var data)) {
+ if (cancel)
+ data.CancellationTokenSource.Cancel ();
+ data.Dispose ();
+ inflightRequests.Remove (task);
+ }
#if !MONOMAC && !MONOTOUCH_WATCH
// do we need to be notified? If we have not inflightData, we do not
if (inflightRequests.Count == 0)
@@ -228,6 +233,7 @@ namespace Foundation {
foreach (var pair in inflightRequests) {
pair.Key?.Cancel ();
pair.Key?.Dispose ();
+ pair.Value?.Dispose ();
}
inflightRequests.Clear ();
@@ -307,6 +313,7 @@ namespace Foundation {
RequestUrl = request.RequestUri.AbsoluteUri,
CompletionSource = tcs,
CancellationToken = cancellationToken,
+ CancellationTokenSource = new CancellationTokenSource (),
Stream = new NSUrlSessionDataTaskStream (),
Request = request
});
@@ -385,7 +392,7 @@ namespace Foundation {
inflight.Stream.TrySetException (new ObjectDisposedException ("The content stream was disposed."));
sessionHandler.RemoveInflightData (dataTask);
- }, inflight.CancellationToken);
+ }, inflight.CancellationTokenSource.Token);
// NB: The double cast is because of a Xamarin compiler bug
var httpResponse = new HttpResponseMessage ((HttpStatusCode)status) {
@@ -449,6 +456,8 @@ namespace Foundation {
// send the error or send the response back
if (error != null) {
+ // got an error, cancel the stream operatios before we do anything
+ inflight.CancellationTokenSource.Cancel ();
inflight.Errored = true;
var exc = createExceptionForNSError (error);
@@ -469,6 +478,9 @@ namespace Foundation {
if (inflight.ResponseSent)
return;
+ if (inflight.CancellationTokenSource.Token.IsCancellationRequested)
+ return;
+
if (inflight.CompletionSource.Task.IsCompleted)
return;
@@ -566,13 +578,14 @@ namespace Foundation {
// Needed since we strip during linking since we're inside a product assembly.
[Preserve (AllMembers = true)]
#endif
- class InflightData
+ class InflightData : IDisposable
{
public readonly object Lock = new object ();
public string RequestUrl { get; set; }
public TaskCompletionSource<HttpResponseMessage> CompletionSource { get; set; }
public CancellationToken CancellationToken { get; set; }
+ public CancellationTokenSource CancellationTokenSource { get; set; }
public NSUrlSessionDataTaskStream Stream { get; set; }
public HttpRequestMessage Request { get; set; }
public HttpResponseMessage Response { get; set; }
@@ -582,6 +595,24 @@ namespace Foundation {
public bool Disposed { get; set; }
public bool Completed { get; set; }
public bool Done { get { return Errored || Disposed || Completed || CancellationToken.IsCancellationRequested; } }
+
+ public void Dispose()
+ {
+ Dispose (true);
+ GC.SuppressFinalize(this);
+ }
+
+ // The bulk of the clean-up code is implemented in Dispose(bool)
+ protected virtual void Dispose (bool disposing)
+ {
+ if (disposing) {
+ if (CancellationTokenSource != null) {
+ CancellationTokenSource.Dispose ();
+ CancellationTokenSource = null;
+ }
+ }
+ }
+
}
#if MONOMAC
@@ -678,7 +709,13 @@ namespace Foundation {
}
}
- await Task.Delay (50).ConfigureAwait (false);
+ try {
+ await Task.Delay (50, cancellationToken).ConfigureAwait (false);
+ } catch (TaskCanceledException ex) {
+ // add a nicer exception for the user to catch, add the cancelation exception
+ // to have a decent stack
+ throw new TimeoutException ("The request timed out.", ex);
+ }
}
// try to throw again before read