Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Allow checking cancellation inside analysis
  • Loading branch information
auduchinok committed Oct 18, 2023
commit cddac92b54ad5a952e52d0813710adc0e3894601
2 changes: 2 additions & 0 deletions src/Compiler/Checking/PatternMatchCompilation.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1146,6 +1146,8 @@ let CompilePatternBasic

// The main recursive loop of the pattern match compiler.
let rec InvestigateFrontiers refuted frontiers =
Cancellable.CheckAndThrow()

match frontiers with
| [] -> failwith "CompilePattern: compile - empty clauses: at least the final clause should always succeed"
| Frontier (i, active, valMap) :: rest ->
Expand Down
2 changes: 2 additions & 0 deletions src/Compiler/Facilities/DiagnosticsLogger.fs
Original file line number Diff line number Diff line change
Expand Up @@ -857,11 +857,13 @@ type StackGuard(maxDepth: int, name: string) =
if depth % maxDepth = 0 then
let diagnosticsLogger = DiagnosticsThreadStatics.DiagnosticsLogger
let buildPhase = DiagnosticsThreadStatics.BuildPhase
let ct = Cancellable.Token

async {
do! Async.SwitchToNewThread()
Thread.CurrentThread.Name <- $"F# Extra Compilation Thread for {name} (depth {depth})"
use _scope = new CompilationGlobalsScope(diagnosticsLogger, buildPhase)
use _token = Cancellable.UsingToken ct
return f ()
}
|> Async.RunImmediate
Expand Down
43 changes: 42 additions & 1 deletion src/Compiler/Utilities/Cancellable.fs
Original file line number Diff line number Diff line change
@@ -1,7 +1,44 @@
namespace FSharp.Compiler

open System
open System.Threading
open Internal.Utilities.Library

[<Sealed>]
type Cancellable =
[<ThreadStatic; DefaultValue>]
static val mutable private tokens: CancellationToken list

static member private Tokens
with get () =
match box Cancellable.tokens with
| Null -> []
| _ -> Cancellable.tokens
and set v = Cancellable.tokens <- v

static member UsingToken(ct) =
Cancellable.Tokens <- ct :: Cancellable.Tokens

{ new IDisposable with
member this.Dispose() =
Cancellable.Tokens <- Cancellable.Tokens |> List.tail }

static member Token =
match Cancellable.Tokens with
| [] -> CancellationToken.None
| token :: _ -> token

static member CheckAndThrow() =
match Cancellable.Tokens with
| [] -> ()
| token :: _ -> token.ThrowIfCancellationRequested()


namespace Internal.Utilities.Library

open System
open System.Threading
open FSharp.Compiler

[<RequireQualifiedAccess; Struct>]
type ValueOrCancelled<'TResult> =
Expand All @@ -17,7 +54,11 @@ module Cancellable =
if ct.IsCancellationRequested then
ValueOrCancelled.Cancelled(OperationCanceledException ct)
else
oper ct
try
use _ = Cancellable.UsingToken(ct)
oper ct
with :? OperationCanceledException as e ->
ValueOrCancelled.Cancelled(OperationCanceledException e.CancellationToken)

let fold f acc seq =
Cancellable(fun ct ->
Expand Down
12 changes: 12 additions & 0 deletions src/Compiler/Utilities/Cancellable.fsi
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
namespace FSharp.Compiler

open System
open System.Threading

[<Sealed>]
type Cancellable =
static member internal UsingToken: CancellationToken -> IDisposable
static member Token: CancellationToken
static member CheckAndThrow: unit -> unit


namespace Internal.Utilities.Library

open System
Expand Down