Skip to content

Parallel compilation fix for TP SDK - #20102

Open
Thorium wants to merge 1 commit into
dotnet:mainfrom
Thorium:parallel-compilation-fix
Open

Parallel compilation fix for TP SDK#20102
Thorium wants to merge 1 commit into
dotnet:mainfrom
Thorium:parallel-compilation-fix

Conversation

@Thorium

@Thorium Thorium commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Description

This is a ported from https://github.com/fsprojects/FSharp.TypeProviders.SDK

Fixes #20060

@Thorium

Thorium commented Jul 30, 2026

Copy link
Copy Markdown
Contributor Author

As far as I understand this goes under "tests" so there is nothing to release, for "release notes".

@github-actions github-actions Bot added the AI-Tooling-Check-Scanned-Clean Tooling check: diff analyzed, no interesting infrastructure files label Jul 30, 2026

@T-Gro T-Gro left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 This review was generated by AI (@expert-reviewer agent). Findings may contain inaccuracies — please verify independently.

This is a faithful port of the parallel-compilation fixes from FSharp.TypeProviders.SDK into the test-data type provider. Overall it looks correct. I traced the new two-lock design and believe it is deadlock-free: typeTablesLock is only ever held for table lookups and target-type shell creation (never while realizing members), while member realization takes realizationLock first and only then reaches into typeTablesLock via convMemberDefToTgt. So the acquisition order is consistently realizationLock → typeTablesLock. Two low-severity observations below — neither is blocking.

type ILPropertyDefs(larr: Lazy<ILPropertyDef[]>) =
let lmap = lazy (
let d = Dictionary<string, ILPropertyDef>()
for p in larr.Force() do d.[p.Name] <- p

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Behavioral change worth confirming: the new dictionary-based TryFindByName uses last-wins (d.[p.Name] <- p), whereas the previous Entries |> Array.tryFind (fun md -> md.Name = name) returned the first matching entry. For IL properties this differs when a type has name-overloaded members (e.g. an indexer Item with multiple index-parameter signatures): GetPropertyImpl(name, ...) will now resolve to the last such property instead of the first. The same first→last shift applies to the analogous field/event/nested-type dict lookups. In practice fields/events/nested types can't share a name, so only overloaded properties are affected; likely harmless for the test providers here, but flagging in case any test relies on the previously-returned member.

// same type's realization on the same thread is fine. The queue writers (AddMember et al.) stay
// unlocked by design: they run either during provider construction, before the compiler observes
// the type, or from a delayed factory that already holds this lock via realization.
let realizationLock = obj()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The correctness of this two-lock scheme depends on a strict acquisition order: realizationLock (this per-type lock) must always be taken before the context-wide typeTablesLock, never the reverse. That invariant holds today because typeTablesLock is only held for table lookups and target-type shell creation, and the getFreshMethods/GetMembersFromCursor factories acquire the source type's realizationLock before calling convMemberDefToTgt (which reaches typeTablesLock). Worth a short comment recording this ordering invariant, since a future edit that realizes members (e.g. calls getMembers/GetMethods) while holding typeTablesLock would introduce an AB–BA deadlock under ParallelCompilation.

@T-Gro
T-Gro self-requested a review August 3, 2026 19:18
@T-Gro T-Gro added the AI-reviewed PR reviewed by AI review council label Aug 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI-reviewed PR reviewed by AI review council AI-Tooling-Check-Scanned-Clean Tooling check: diff analyzed, no interesting infrastructure files

Projects

Status: New

Development

Successfully merging this pull request may close these issues.

The new dotnet SDK ParallelCompilation=true causing issues in TypeProviders

2 participants