Commit fdb90bf
Lock Composer autoload around phar:// reads in forked workers
Alternative approach to making the experimental pcntl_fork() worker
path work when PHPStan is run from a .phar. Where #5669 extracts the
phar before forking and reroutes every phar:// read to disk, this
takes the opposite tack: leave PHP's built-in phar:// wrapper in
place but serialise the racy operation.
PHP's built-in phar:// stream wrapper caches a single fd for the
running .phar; after pcntl_fork() that fd's open file description
(and its seek cursor) is shared between parent and every forked
child, so concurrent lazy class loads across workers can interleave
and read garbage offsets — surfacing as spurious parse errors against
phar-internal files.
PharAutoloaderLock::install() wraps every registered Composer
ClassLoader so loadClass() acquires an exclusive flock on a tmp file
before its `include` and releases it after. Two workers can never
hold the lock simultaneously, so they can never be inside
`include 'phar://…'` simultaneously, so the cursor can't be moved
out from under either of them.
Cost: per-class load takes one flock pair. Each worker contends with
siblings only during its initial "loading wave" — a few hundred
classes touched once. After its symbol table is populated the lock
is never taken again and workers run fully parallel for the rest of
the analysis.
Covers only class autoload. Non-class phar reads
(file_get_contents('phar://…'), stat, dir iteration) still go through
the unlocked built-in wrapper; in practice those happen during boot,
which is pre-fork, so they don't race.
ParallelAnalyser and FixerApplication call the (idempotent) install()
once they have decided to take the fork path. No-op when not running
inside a phar.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent a4d403a commit fdb90bf
3 files changed
Lines changed: 112 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
25 | 25 | | |
26 | 26 | | |
27 | 27 | | |
| 28 | + | |
28 | 29 | | |
29 | 30 | | |
30 | 31 | | |
| |||
100 | 101 | | |
101 | 102 | | |
102 | 103 | | |
| 104 | + | |
103 | 105 | | |
104 | 106 | | |
105 | 107 | | |
| |||
457 | 459 | | |
458 | 460 | | |
459 | 461 | | |
| 462 | + | |
| 463 | + | |
| 464 | + | |
| 465 | + | |
| 466 | + | |
460 | 467 | | |
461 | | - | |
| 468 | + | |
462 | 469 | | |
463 | 470 | | |
464 | 471 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
54 | 54 | | |
55 | 55 | | |
56 | 56 | | |
| 57 | + | |
57 | 58 | | |
58 | 59 | | |
59 | 60 | | |
| |||
175 | 176 | | |
176 | 177 | | |
177 | 178 | | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
178 | 182 | | |
179 | 183 | | |
180 | 184 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
0 commit comments