Skip to content

Commit 4c0a592

Browse files
authored
NodeCode.Parallel keeps ThreadStatics (#16576)
1 parent 544a1c9 commit 4c0a592

File tree

2 files changed

+53
-1
lines changed

2 files changed

+53
-1
lines changed

src/Compiler/Facilities/BuildGraph.fs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,19 @@ type NodeCode private () =
193193
}
194194

195195
static member Parallel(computations: NodeCode<'T> seq) =
196-
computations |> Seq.map (fun (Node x) -> x) |> Async.Parallel |> Node
196+
let diagnosticsLogger = DiagnosticsThreadStatics.DiagnosticsLogger
197+
let phase = DiagnosticsThreadStatics.BuildPhase
198+
199+
computations
200+
|> Seq.map (fun (Node x) ->
201+
async {
202+
DiagnosticsThreadStatics.DiagnosticsLogger <- diagnosticsLogger
203+
DiagnosticsThreadStatics.BuildPhase <- phase
204+
return! x
205+
})
206+
|> Async.Parallel
207+
|> wrapThreadStaticInfo
208+
|> Node
197209

198210
[<RequireQualifiedAccess>]
199211
module GraphNode =

tests/FSharp.Compiler.UnitTests/BuildGraphTests.fs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ open Xunit
88
open FSharp.Test
99
open FSharp.Test.Compiler
1010
open FSharp.Compiler.BuildGraph
11+
open FSharp.Compiler.DiagnosticsLogger
1112
open Internal.Utilities.Library
1213

1314
module BuildGraphTests =
@@ -233,3 +234,42 @@ module BuildGraphTests =
233234

234235
Assert.shouldBeTrue graphNode.HasValue
235236
Assert.shouldBe (ValueSome 1) (graphNode.TryPeekValue())
237+
238+
239+
[<Fact>]
240+
let internal ``NodeCode preserves DiagnosticsThreadStatics`` () =
241+
let random =
242+
let rng = Random()
243+
fun n -> rng.Next n
244+
245+
let job phase _ = node {
246+
do! random 10 |> Async.Sleep |> NodeCode.AwaitAsync
247+
Assert.Equal(phase, DiagnosticsThreadStatics.BuildPhase)
248+
}
249+
250+
let work (phase: BuildPhase) =
251+
node {
252+
use _ = new CompilationGlobalsScope(DiscardErrorsLogger, phase)
253+
let! _ = Seq.init 8 (job phase) |> NodeCode.Parallel
254+
Assert.Equal(phase, DiagnosticsThreadStatics.BuildPhase)
255+
}
256+
257+
let phases = [|
258+
BuildPhase.DefaultPhase
259+
BuildPhase.Compile
260+
BuildPhase.Parameter
261+
BuildPhase.Parse
262+
BuildPhase.TypeCheck
263+
BuildPhase.CodeGen
264+
BuildPhase.Optimize
265+
BuildPhase.IlxGen
266+
BuildPhase.IlGen
267+
BuildPhase.Output
268+
BuildPhase.Interactive
269+
|]
270+
271+
let pickRandomPhase _ = phases[random phases.Length]
272+
Seq.init 100 pickRandomPhase
273+
|> Seq.map (work >> Async.AwaitNodeCode)
274+
|> Async.Parallel
275+
|> Async.RunSynchronously

0 commit comments

Comments
 (0)