Skip to content

fix: serialize mkdir shell fork on the run_command lock#1298

Open
krystophny wants to merge 1 commit into
fortran-lang:mainfrom
krystophny:fix/mkdir-fork-gap
Open

fix: serialize mkdir shell fork on the run_command lock#1298
krystophny wants to merge 1 commit into
fortran-lang:mainfrom
krystophny:fix/mkdir-fork-gap

Conversation

@krystophny

@krystophny krystophny commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Move directory creation in build_target from an unnamed !$omp critical
    to the named critical(run_command) lock that guards all other shell forks
  • mkdir shells out twice (is_dir runs test -d, then mkdir -p), both of
    which fork; the unnamed critical was a different lock than run_command, so a
    mkdir fork on one thread could run concurrently with a compile/link/archive
    shell fallback on another — the exact concurrent-fork hazard the
    run_command lock exists to prevent

Merge order

Independent — no ordering constraint. Logically related to the argv spawn chain
but does not depend on it.

Note: textual overlap with #1289 (interface-aware rebuild) — both edit the
!$omp critical block in build_target. Whichever merges second rebases.

Independent PRs (any order):

Stacked chain (merge in order):

  1. Fortran compiles via argv (feat: exec Fortran compiles via argv (posix_spawn/CreateProcess) #1299)
  2. Parallel link/archive via argv (feat: run link and archive in parallel via argv spawn #1300)
  3. C/C++ compiles via argv (feat: exec C/C++ compiles via argv, close the shell-fork gap #1301)

Fork-safety fix:

After the above:

Refs: #962

Verification

$ fpm build --flag -fopenmp
[100%] Project compiled successfully.

$ fpm test --flag -fopenmp
TALLY;TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
PASSED: all 35 tests passed

build_target created the output directory inside an unnamed `!$omp critical`.
mkdir shells out twice (is_dir runs `test -d`, then `mkdir -p`), and both
fork. The unnamed critical is a different lock than `critical(run_command)`
that guards every other shell fork (the compile/link/archive fallbacks), so a
mkdir fork on one thread could run concurrently with a run_command fork on
another - the exact concurrent-fork hazard the run_command lock exists to
prevent. Put the directory creation under `critical(run_command)` so all
shell forks share one lock.
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