Skip to content

Commit

Permalink
Fix concurrency issue in ILPreTypeDefImpl (#17812)
Browse files Browse the repository at this point in the history
* use standard lazy

* rn
  • Loading branch information
majocha authored Sep 30, 2024
1 parent 1bf093f commit e754739
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 26 deletions.
3 changes: 2 additions & 1 deletion docs/release-notes/.FSharp.Compiler.Service/9.0.200.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

* Fix internal error when calling 'AddSingleton' and other overloads only differing in generic arity ([PR #17804](https://github.com/dotnet/fsharp/pull/17804))
* Fix extension methods support for non-reference system assemblies ([PR #17799](https://github.com/dotnet/fsharp/pull/17799))
* Ensure `frameworkTcImportsCache` mutations are threadsafe. ([PR #17795](https://github.com/dotnet/fsharp/pull/17795))
* Ensure `frameworkTcImportsCache` mutations are thread-safe. ([PR #17795](https://github.com/dotnet/fsharp/pull/17795))
* Fix concurrency issue in `ILPreTypeDefImpl` ([PR #17812](https://github.com/dotnet/fsharp/pull/17812))


### Added
Expand Down
32 changes: 7 additions & 25 deletions src/Compiler/AbstractIL/il.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2913,35 +2913,17 @@ and [<NoEquality; NoComparison>] ILPreTypeDef =

/// This is a memory-critical class. Very many of these objects get allocated and held to represent the contents of .NET assemblies.
and [<Sealed>] ILPreTypeDefImpl(nameSpace: string list, name: string, metadataIndex: int32, storage: ILTypeDefStored) =
let mutable store: ILTypeDef = Unchecked.defaultof<_>
let mutable storage = storage
let stored =
lazy
match storage with
| ILTypeDefStored.Given td -> td
| ILTypeDefStored.Computed f -> f ()
| ILTypeDefStored.Reader f -> f metadataIndex

interface ILPreTypeDef with
member _.Namespace = nameSpace
member _.Name = name

member x.GetTypeDef() =
match box store with
| null ->
let syncObj = storage
Monitor.Enter(syncObj)

try
match box store with
| null ->
let value =
match storage with
| ILTypeDefStored.Given td -> td
| ILTypeDefStored.Computed f -> f ()
| ILTypeDefStored.Reader f -> f metadataIndex

store <- value
storage <- Unchecked.defaultof<_>
value
| _ -> store
finally
Monitor.Exit(syncObj)
| _ -> store
member x.GetTypeDef() = stored.Value

and ILTypeDefStored =
| Given of ILTypeDef
Expand Down

0 comments on commit e754739

Please sign in to comment.