Skip to content

fix(pool): release the last job's arrays; no writes after a recovered caller panic - #33

Merged
tannevaled merged 1 commit into
mainfrom
fix/pool-retention
Oct 7, 2026
Merged

tannevaled merged 1 commit into
mainfrom
fix/pool-retention

Conversation

@tannevaled

Copy link
Copy Markdown
Contributor

Security audit of the helper pool added in v0.6.0 (#31). Two defects, both fixed. Each fix comes with a test that fails without it.

1. Retention of the last operation's arrays

pool.job kept the last job, and its closure holds the operands. The arrays of the last parallel operation therefore could not be garbage-collected until another parallel operation replaced the job. That is up to the largest array, for as long as the program runs.

  • Fix: once all blocks are done, the caller swaps in an empty noJob (w = 0, so no helper takes it). A helper that loaded the real job just before finds every block taken and drops it on return.
  • Test: TestPoolDoesNotRetainLastJob uses a weak pointer plus runtime.GC(). It fails on v0.6.0. A first version passed on the defective code because its closure captured a variable that the test then set to nil; it now captures a function parameter.

2. Writes after a recovered panic in the caller

Since v0.6.0 the caller runs blocks itself. If body panicked there (a user Map function, for example), the panic propagated while the helpers kept writing into the arrays of a caller that might recover it.

  • Fix: on a panic, the caller closes every run (no new claims), waits for the in-flight blocks, retires the job, then re-panics.
  • Test: TestPoolCallerPanicStopsTheHelpers checks that no block starts after the panic propagates and that the pool keeps working. Removing the wait makes it fail ("1 blocks ran after the panic propagated").
  • Untested by design: removing only the closing of the runs is not caught. The wait alone usually outlasts all the work; the closing covers the instant when running touches zero between two blocks, which no test can target reliably. That reasoning is written in the code.
  • Unchanged: a panic on a helper goroutine still ends the program, as before v0.6.0. Map's doc now says so.

Checks

  • -race, coverage 100%.
  • go vet on linux amd64/ppc64le/loong64/386/riscv64.
  • govulncheck: none.
  • SECURITY.md audit-log entry.

Version: v0.6.1.

🤖 Generated with Claude Code

… caller panic propagates

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@tannevaled
tannevaled merged commit f3fc70b into main Oct 7, 2026
12 checks passed
@tannevaled
tannevaled deleted the fix/pool-retention branch October 7, 2026 16:17
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