Skip to content

Commit d4e3b26

Browse files
authored
Cancellable: set token from node/async in features code (#16348)
* Cancellable: set token from node/async in features code * Fantomas * Fix wrong token * Remove assert * Set token in fsi * Use cancellation token default value instead of option * More cancellation token in fsi
1 parent 8cc0726 commit d4e3b26

File tree

6 files changed

+65
-27
lines changed

6 files changed

+65
-27
lines changed

src/Compiler/Facilities/BuildGraph.fs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,14 @@ let wrapThreadStaticInfo computation =
1717
async {
1818
let diagnosticsLogger = DiagnosticsThreadStatics.DiagnosticsLogger
1919
let phase = DiagnosticsThreadStatics.BuildPhase
20+
let ct = Cancellable.Token
2021

2122
try
2223
return! computation
2324
finally
2425
DiagnosticsThreadStatics.DiagnosticsLogger <- diagnosticsLogger
2526
DiagnosticsThreadStatics.BuildPhase <- phase
27+
Cancellable.Token <- ct
2628
}
2729

2830
type Async<'T> with
@@ -125,20 +127,23 @@ type NodeCode private () =
125127
static member RunImmediate(computation: NodeCode<'T>, ct: CancellationToken) =
126128
let diagnosticsLogger = DiagnosticsThreadStatics.DiagnosticsLogger
127129
let phase = DiagnosticsThreadStatics.BuildPhase
130+
let ct2 = Cancellable.Token
128131

129132
try
130133
try
131134
let work =
132135
async {
133136
DiagnosticsThreadStatics.DiagnosticsLogger <- diagnosticsLogger
134137
DiagnosticsThreadStatics.BuildPhase <- phase
138+
Cancellable.Token <- ct2
135139
return! computation |> Async.AwaitNodeCode
136140
}
137141

138142
Async.StartImmediateAsTask(work, cancellationToken = ct).Result
139143
finally
140144
DiagnosticsThreadStatics.DiagnosticsLogger <- diagnosticsLogger
141145
DiagnosticsThreadStatics.BuildPhase <- phase
146+
Cancellable.Token <- ct2
142147
with :? AggregateException as ex when ex.InnerExceptions.Count = 1 ->
143148
raise (ex.InnerExceptions[0])
144149

@@ -148,19 +153,22 @@ type NodeCode private () =
148153
static member StartAsTask_ForTesting(computation: NodeCode<'T>, ?ct: CancellationToken) =
149154
let diagnosticsLogger = DiagnosticsThreadStatics.DiagnosticsLogger
150155
let phase = DiagnosticsThreadStatics.BuildPhase
156+
let ct2 = Cancellable.Token
151157

152158
try
153159
let work =
154160
async {
155161
DiagnosticsThreadStatics.DiagnosticsLogger <- diagnosticsLogger
156162
DiagnosticsThreadStatics.BuildPhase <- phase
163+
Cancellable.Token <- ct2
157164
return! computation |> Async.AwaitNodeCode
158165
}
159166

160167
Async.StartAsTask(work, cancellationToken = defaultArg ct CancellationToken.None)
161168
finally
162169
DiagnosticsThreadStatics.DiagnosticsLogger <- diagnosticsLogger
163170
DiagnosticsThreadStatics.BuildPhase <- phase
171+
Cancellable.Token <- ct2
164172

165173
static member CancellationToken = cancellationToken
166174

src/Compiler/Interactive/fsi.fs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4089,6 +4089,7 @@ type FsiInteractionProcessor
40894089
?cancellationToken: CancellationToken
40904090
) =
40914091
let cancellationToken = defaultArg cancellationToken CancellationToken.None
4092+
use _ = Cancellable.UsingToken(cancellationToken)
40924093

40934094
if tokenizer.LexBuffer.IsPastEndOfStream then
40944095
let stepStatus =
@@ -4217,6 +4218,7 @@ type FsiInteractionProcessor
42174218

42184219
member _.EvalInteraction(ctok, sourceText, scriptFileName, diagnosticsLogger, ?cancellationToken) =
42194220
let cancellationToken = defaultArg cancellationToken CancellationToken.None
4221+
use _ = Cancellable.UsingToken(cancellationToken)
42204222
use _ = UseBuildPhase BuildPhase.Interactive
42214223
use _ = UseDiagnosticsLogger diagnosticsLogger
42224224
use _scope = SetCurrentUICultureForThread fsiOptions.FsiLCID
@@ -4893,6 +4895,7 @@ type FsiEvaluationSession
48934895
SpawnInteractiveServer(fsi, fsiOptions, fsiConsoleOutput)
48944896

48954897
use _ = UseBuildPhase BuildPhase.Interactive
4898+
use _ = Cancellable.UsingToken(CancellationToken.None)
48964899

48974900
if fsiOptions.Interact then
48984901
// page in the type check env

src/Compiler/Service/FSharpCheckerResults.fs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3560,6 +3560,9 @@ type FsiInteractiveChecker(legacyReferenceResolver, tcConfig: TcConfig, tcGlobal
35603560

35613561
member _.ParseAndCheckInteraction(sourceText: ISourceText, ?userOpName: string) =
35623562
cancellable {
3563+
let! ct = Cancellable.token ()
3564+
use _ = Cancellable.UsingToken(ct)
3565+
35633566
let userOpName = defaultArg userOpName "Unknown"
35643567
let fileName = Path.Combine(tcConfig.implicitIncludeDir, "stdin.fsx")
35653568
let suggestNamesForErrors = true // Will always be true, this is just for readability

src/Compiler/Service/service.fs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,9 @@ type BackgroundCompiler
500500
Activity.Tags.cache, cache.ToString()
501501
|]
502502

503+
let! ct = Async.CancellationToken
504+
use _ = Cancellable.UsingToken(ct)
505+
503506
if cache then
504507
let hash = sourceText.GetHashCode() |> int64
505508

@@ -541,6 +544,9 @@ type BackgroundCompiler
541544
"BackgroundCompiler.GetBackgroundParseResultsForFileInProject"
542545
[| Activity.Tags.fileName, fileName; Activity.Tags.userOpName, userOpName |]
543546

547+
let! ct = NodeCode.CancellationToken
548+
use _ = Cancellable.UsingToken(ct)
549+
544550
let! builderOpt, creationDiags = getOrCreateBuilder (options, userOpName)
545551

546552
match builderOpt with
@@ -690,6 +696,9 @@ type BackgroundCompiler
690696
Activity.Tags.userOpName, userOpName
691697
|]
692698

699+
let! ct = NodeCode.CancellationToken
700+
use _ = Cancellable.UsingToken(ct)
701+
693702
let! cachedResults =
694703
node {
695704
let! builderOpt, creationDiags = getAnyBuilder (options, userOpName)
@@ -732,6 +741,9 @@ type BackgroundCompiler
732741
Activity.Tags.userOpName, userOpName
733742
|]
734743

744+
let! ct = NodeCode.CancellationToken
745+
use _ = Cancellable.UsingToken(ct)
746+
735747
let! builderOpt, creationDiags = getOrCreateBuilder (options, userOpName)
736748

737749
match builderOpt with
@@ -760,6 +772,9 @@ type BackgroundCompiler
760772
Activity.Tags.userOpName, userOpName
761773
|]
762774

775+
let! ct = NodeCode.CancellationToken
776+
use _ = Cancellable.UsingToken(ct)
777+
763778
let! builderOpt, creationDiags = getOrCreateBuilder (options, userOpName)
764779

765780
match builderOpt with
@@ -815,6 +830,9 @@ type BackgroundCompiler
815830
Activity.Tags.userOpName, userOpName
816831
|]
817832

833+
let! ct = NodeCode.CancellationToken
834+
use _ = Cancellable.UsingToken(ct)
835+
818836
let! builderOpt, _ = getOrCreateBuilder (options, userOpName)
819837

820838
match builderOpt with
@@ -834,6 +852,9 @@ type BackgroundCompiler
834852
Activity.Tags.userOpName, userOpName
835853
|]
836854

855+
let! ct = NodeCode.CancellationToken
856+
use _ = Cancellable.UsingToken(ct)
857+
837858
let! builderOpt, creationDiags = getOrCreateBuilder (options, userOpName)
838859

839860
match builderOpt with
@@ -974,6 +995,9 @@ type BackgroundCompiler
974995
Activity.Tags.userOpName, userOpName
975996
|]
976997

998+
let! ct = NodeCode.CancellationToken
999+
use _ = Cancellable.UsingToken(ct)
1000+
9771001
let! builderOpt, _ = getOrCreateBuilder (options, userOpName)
9781002

9791003
match builderOpt with
@@ -1016,6 +1040,9 @@ type BackgroundCompiler
10161040
/// Parse and typecheck the whole project (the implementation, called recursively as project graph is evaluated)
10171041
member private _.ParseAndCheckProjectImpl(options, userOpName) =
10181042
node {
1043+
let! ct = NodeCode.CancellationToken
1044+
use _ = Cancellable.UsingToken(ct)
1045+
10191046
let! builderOpt, creationDiags = getOrCreateBuilder (options, userOpName)
10201047

10211048
match builderOpt with
@@ -1149,6 +1176,9 @@ type BackgroundCompiler
11491176
// Do we assume .NET Framework references for scripts?
11501177
let assumeDotNetFramework = defaultArg assumeDotNetFramework true
11511178

1179+
let! ct = Cancellable.token ()
1180+
use _ = Cancellable.UsingToken(ct)
1181+
11521182
let extraFlags =
11531183
if previewEnabled then
11541184
[| "--langversion:preview" |]
@@ -1269,6 +1299,9 @@ type BackgroundCompiler
12691299
|]
12701300

12711301
async {
1302+
let! ct = Async.CancellationToken
1303+
use _ = Cancellable.UsingToken(ct)
1304+
12721305
let! ct = Async.CancellationToken
12731306
// If there was a similar entry (as there normally will have been) then re-establish an empty builder . This
12741307
// is a somewhat arbitrary choice - it will have the effect of releasing memory associated with the previous
@@ -1514,6 +1547,9 @@ type FSharpChecker
15141547
use _ = Activity.start "FSharpChecker.Compile" [| Activity.Tags.userOpName, _userOpName |]
15151548

15161549
async {
1550+
let! ct = Async.CancellationToken
1551+
use _ = Cancellable.UsingToken(ct)
1552+
15171553
let ctok = CompilationThreadToken()
15181554
return CompileHelpers.compileFromArgs (ctok, argv, legacyReferenceResolver, None, None)
15191555
}
@@ -1633,6 +1669,9 @@ type FSharpChecker
16331669
let userOpName = defaultArg userOpName "Unknown"
16341670

16351671
node {
1672+
let! ct = NodeCode.CancellationToken
1673+
use _ = Cancellable.UsingToken(ct)
1674+
16361675
if fastCheck <> Some true || not captureIdentifiersWhenParsing then
16371676
return! backgroundCompiler.FindReferencesInFile(fileName, options, symbol, canInvalidateProject, userOpName)
16381677
else

src/Compiler/Utilities/Cancellable.fs

Lines changed: 11 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,47 +2,32 @@ namespace FSharp.Compiler
22

33
open System
44
open System.Threading
5-
open Internal.Utilities.Library
65

76
[<Sealed>]
87
type Cancellable =
98
[<ThreadStatic; DefaultValue>]
10-
static val mutable private tokens: CancellationToken list
9+
static val mutable private token: CancellationToken
1110

12-
static let disposable =
13-
{ new IDisposable with
14-
member this.Dispose() =
15-
Cancellable.Tokens <- Cancellable.Tokens |> List.tail
16-
}
11+
static member UsingToken(ct) =
12+
let oldCt = Cancellable.token
1713

18-
static member Tokens
19-
with private get () =
20-
match box Cancellable.tokens with
21-
| Null -> []
22-
| _ -> Cancellable.tokens
23-
and private set v = Cancellable.tokens <- v
14+
Cancellable.token <- ct
2415

25-
static member UsingToken(ct) =
26-
Cancellable.Tokens <- ct :: Cancellable.Tokens
27-
disposable
16+
{ new IDisposable with
17+
member this.Dispose() = Cancellable.token <- oldCt
18+
}
2819

29-
static member Token =
30-
match Cancellable.Tokens with
31-
| [] -> CancellationToken.None
32-
| token :: _ -> token
20+
static member Token
21+
with get () = Cancellable.token
22+
and internal set v = Cancellable.token <- v
3323

34-
/// There may be multiple tokens if `UsingToken` is called multiple times, producing scoped structure.
35-
/// We're interested in the current, i.e. the most recent, one.
3624
static member CheckAndThrow() =
37-
match Cancellable.Tokens with
38-
| [] -> ()
39-
| token :: _ -> token.ThrowIfCancellationRequested()
25+
Cancellable.token.ThrowIfCancellationRequested()
4026

4127
namespace Internal.Utilities.Library
4228

4329
open System
4430
open System.Threading
45-
open FSharp.Compiler
4631

4732
#if !FSHARPCORE_USE_PACKAGE
4833
open FSharp.Core.CompilerServices.StateMachineHelpers
@@ -63,7 +48,6 @@ module Cancellable =
6348
ValueOrCancelled.Cancelled(OperationCanceledException ct)
6449
else
6550
try
66-
use _ = Cancellable.UsingToken(ct)
6751
oper ct
6852
with :? OperationCanceledException as e ->
6953
ValueOrCancelled.Cancelled(OperationCanceledException e.CancellationToken)

src/Compiler/Utilities/Cancellable.fsi

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ open System.Threading
77
type Cancellable =
88
static member internal UsingToken: CancellationToken -> IDisposable
99
static member Token: CancellationToken
10+
static member internal Token: CancellationToken with set
1011
static member CheckAndThrow: unit -> unit
1112

1213
namespace Internal.Utilities.Library

0 commit comments

Comments
 (0)