From d71b02b2fe581d2cc884e297e1c3effa3a611111 Mon Sep 17 00:00:00 2001 From: Saul Rennison Date: Sat, 1 Apr 2017 20:48:28 +0100 Subject: [PATCH 1/3] Initial attempt at passing in cancellation tokens/tasks to OperationCanceledException and TaskCanceledException Fixes #2100 --- src/fsharp/FSharp.Core/control.fs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/fsharp/FSharp.Core/control.fs b/src/fsharp/FSharp.Core/control.fs index 316ba9a34d6..2d86f996a71 100644 --- a/src/fsharp/FSharp.Core/control.fs +++ b/src/fsharp/FSharp.Core/control.fs @@ -767,7 +767,7 @@ namespace Microsoft.FSharp.Control // Call the cancellation continuation let cancelT (args:AsyncParams<_>) = - args.aux.ccont (new OperationCanceledException()) + args.aux.ccont (new OperationCanceledException(args.aux.token)) // Build a primitive without any exception of resync protection // @@ -1541,8 +1541,8 @@ namespace Microsoft.FSharp.Control let continuation (completedTask : Task<_>) : unit = args.aux.trampolineHolder.Protect((fun () -> if completedTask.IsCanceled then - if useCcontForTaskCancellation then args.aux.ccont(new OperationCanceledException()) - else args.aux.econt (ExceptionDispatchInfo.Capture(new TaskCanceledException())) + if useCcontForTaskCancellation then args.aux.ccont(new OperationCanceledException(args.aux.token)) + else args.aux.econt (ExceptionDispatchInfo.Capture(new TaskCanceledException(completedTask))) elif completedTask.IsFaulted then args.aux.econt (MayLoseStackTrace(completedTask.Exception)) else @@ -1555,8 +1555,8 @@ namespace Microsoft.FSharp.Control let continuation (completedTask : Task) : unit = args.aux.trampolineHolder.Protect((fun () -> if completedTask.IsCanceled then - if useCcontForTaskCancellation then args.aux.ccont (new OperationCanceledException()) - else args.aux.econt (ExceptionDispatchInfo.Capture(new TaskCanceledException())) + if useCcontForTaskCancellation then args.aux.ccont (new OperationCanceledException(args.aux.token)) + else args.aux.econt (ExceptionDispatchInfo.Capture(new TaskCanceledException(completedTask))) elif completedTask.IsFaulted then args.aux.econt (MayLoseStackTrace(completedTask.Exception)) else @@ -1630,7 +1630,7 @@ namespace Microsoft.FSharp.Control match !timer with | None -> () | Some t -> t.Dispose() - aux.trampolineHolder.Protect(fun () -> savedCCont(new OperationCanceledException())) |> unfake + aux.trampolineHolder.Protect(fun () -> savedCCont(new OperationCanceledException(aux.token))) |> unfake ), null) let mutable edi = null @@ -1695,7 +1695,7 @@ namespace Microsoft.FSharp.Control Async.Start (async { do (ccont e |> unfake) }) // register cancellation handler - let registration = aux.token.Register(fun () -> cancel (OperationCanceledException())) + let registration = aux.token.Register(fun () -> cancel (OperationCanceledException(aux.token))) // run actual await routine // callback will be executed on the thread pool so we need to use TrampolineHolder.Protect to install trampoline @@ -1746,7 +1746,7 @@ namespace Microsoft.FSharp.Control match !rwh with | None -> () | Some rwh -> rwh.Unregister(null) |> ignore) - Async.Start (async { do (aux.ccont (OperationCanceledException()) |> unfake) })) + Async.Start (async { do (aux.ccont (OperationCanceledException(aux.token)) |> unfake) })) and registration : CancellationTokenRegistration = aux.token.Register(cancelHandler, null) @@ -1842,7 +1842,7 @@ namespace Microsoft.FSharp.Control // Register the result. This may race with a successful result, but // ResultCell allows a race and throws away whichever comes last. once.Do(fun () -> - let canceledResult = Canceled (OperationCanceledException()) + let canceledResult = Canceled (OperationCanceledException(cancellationToken)) resultCell.RegisterResult(canceledResult,reuseThread=true) |> unfake ) | Some cancel -> @@ -2007,7 +2007,7 @@ namespace Microsoft.FSharp.Control event.RemoveHandler(del) // Register the result. This may race with a successful result, but // ResultCell allows a race and throws away whichever comes last. - once.Do(fun () -> resultCell.RegisterResult(Canceled (OperationCanceledException()),reuseThread=true) |> unfake) + once.Do(fun () -> resultCell.RegisterResult(Canceled (OperationCanceledException(token)),reuseThread=true) |> unfake) | Some cancel -> // If we get an exception from a cooperative cancellation function // we assume the operation has already completed. From 07747ba68b84f4113fafb23e37ea7cccb5e84bac Mon Sep 17 00:00:00 2001 From: Saul Rennison Date: Sat, 1 Apr 2017 21:00:08 +0100 Subject: [PATCH 2/3] Updated remaining references to OperationCanceledException --- src/absil/illib.fs | 2 +- src/fsharp/vs/Reactor.fs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/absil/illib.fs b/src/absil/illib.fs index cda35818c1d..5f7a72d0c01 100644 --- a/src/absil/illib.fs +++ b/src/absil/illib.fs @@ -762,7 +762,7 @@ module Cancellable = let token () = Cancellable (fun ct -> ValueOrCancelled.Value ct) /// Represents a canceled computation - let canceled() = Cancellable (fun _ -> ValueOrCancelled.Cancelled (new OperationCanceledException())) + let canceled() = Cancellable (fun ct -> ValueOrCancelled.Cancelled (new OperationCanceledException(ct))) /// Catch exceptions in a computation let private catch (Cancellable e) = diff --git a/src/fsharp/vs/Reactor.fs b/src/fsharp/vs/Reactor.fs index 7aff63662e5..3924bf68a73 100755 --- a/src/fsharp/vs/Reactor.fs +++ b/src/fsharp/vs/Reactor.fs @@ -152,7 +152,7 @@ type Reactor() = with e -> e |> AsyncUtil.AsyncException resultCell.RegisterResult(result)), - ccont=(fun () -> resultCell.RegisterResult (AsyncUtil.AsyncCanceled(OperationCanceledException())) ) + ccont=(fun () -> resultCell.RegisterResult (AsyncUtil.AsyncCanceled(OperationCanceledException(ctok))) ) ) return! resultCell.AsyncResult From 42cf793ce98a1a0977011f12b478868fa711c802 Mon Sep 17 00:00:00 2001 From: Saul Rennison Date: Sat, 1 Apr 2017 22:36:20 +0100 Subject: [PATCH 3/3] Fix Reactor compilation --- src/fsharp/vs/Reactor.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fsharp/vs/Reactor.fs b/src/fsharp/vs/Reactor.fs index 3924bf68a73..ef809b734b2 100755 --- a/src/fsharp/vs/Reactor.fs +++ b/src/fsharp/vs/Reactor.fs @@ -152,7 +152,7 @@ type Reactor() = with e -> e |> AsyncUtil.AsyncException resultCell.RegisterResult(result)), - ccont=(fun () -> resultCell.RegisterResult (AsyncUtil.AsyncCanceled(OperationCanceledException(ctok))) ) + ccont=(fun () -> resultCell.RegisterResult (AsyncUtil.AsyncCanceled(OperationCanceledException(ct))) ) ) return! resultCell.AsyncResult