Skip to content

Commit

Permalink
use AsyncLocal for Cancellable token
Browse files Browse the repository at this point in the history
  • Loading branch information
majocha committed Feb 3, 2024
1 parent e08be38 commit d84c21c
Showing 1 changed file with 8 additions and 25 deletions.
33 changes: 8 additions & 25 deletions src/Compiler/Utilities/Cancellable.fs
Original file line number Diff line number Diff line change
Expand Up @@ -6,37 +6,20 @@ open Internal.Utilities.Library

[<Sealed>]
type Cancellable =
[<ThreadStatic; DefaultValue>]
static val mutable private tokens: CancellationToken list
static let token = AsyncLocal<CancellationToken>()

static member UsingToken(ct) =
let previousToken = token.Value
token.Value <- ct

static let disposable =
{ new IDisposable with
member this.Dispose() =
Cancellable.Tokens <- Cancellable.Tokens |> List.tail
member this.Dispose() = token.Value <- previousToken
}

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

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

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

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

namespace Internal.Utilities.Library

Expand Down

0 comments on commit d84c21c

Please sign in to comment.