Skip to content

fix: read result validity before Merge redeems it to the pool#260

Merged
fredbi merged 1 commit into
go-openapi:masterfrom
fredbi:fix/race-condition
Jun 10, 2026
Merged

fix: read result validity before Merge redeems it to the pool#260
fredbi merged 1 commit into
go-openapi:masterfrom
fredbi:fix/race-condition

Conversation

@fredbi

@fredbi fredbi commented Jun 10, 2026

Copy link
Copy Markdown
Member

validateRequiredDefinitions read red.IsValid() after res.Merge(red). Merge redeems a result whose wantsRedeemOnMerge is set (true for any pool-borrowed result) back into the process-global sync.Pool. Reading red after that point races with a concurrent Spec() goroutine borrowing the same *Result and calling cleared() on it.

This surfaced as a rare data race under -race in Test_ParallelPool:

Write at ... Result.cleared() <- resultsPool.BorrowResult()
Previous read ... Result.IsValid() <- validateRequiredDefinitions

Capture validity into a local before merging, matching the read-before- merge pattern used everywhere else (e.g. validateRequiredProperties, default/example validators).

Change type

Please select: 🆕 New feature or enhancement|🔧 Bug fix'|📃 Documentation update

Short description

Fixes

Full description

Checklist

  • I have signed all my commits with my name and email (see DCO. This does not require a PGP-signed commit
  • I have rebased and squashed my work, so only one commit remains
  • I have added tests to cover my changes.
  • I have properly enriched go doc comments in code.
  • I have properly documented any breaking change.

validateRequiredDefinitions read red.IsValid() *after* res.Merge(red).
Merge redeems a result whose wantsRedeemOnMerge is set (true for any
pool-borrowed result) back into the process-global sync.Pool. Reading
red after that point races with a concurrent Spec() goroutine borrowing
the same *Result and calling cleared() on it.

This surfaced as a rare data race under -race in Test_ParallelPool:

  Write at ... Result.cleared() <- resultsPool.BorrowResult()
  Previous read ... Result.IsValid() <- validateRequiredDefinitions

Capture validity into a local before merging, matching the read-before-
merge pattern used everywhere else (e.g. validateRequiredProperties,
default/example validators).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
@fredbi fredbi force-pushed the fix/race-condition branch from c4c4eb9 to 8dae61a Compare June 10, 2026 16:01
@codecov

codecov Bot commented Jun 10, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 92.35%. Comparing base (84c917d) to head (8dae61a).
⚠️ Report is 1 commits behind head on master.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #260      +/-   ##
==========================================
- Coverage   92.41%   92.35%   -0.06%     
==========================================
  Files          24       24              
  Lines        3271     3272       +1     
==========================================
- Hits         3023     3022       -1     
- Misses        163      165       +2     
  Partials       85       85              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

@fredbi fredbi merged commit 799b897 into go-openapi:master Jun 10, 2026
27 of 35 checks passed
@fredbi fredbi deleted the fix/race-condition branch June 10, 2026 16:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant