authorgravatar for squeek502@hotmail.comRyan Liptak <squeek502@hotmail.com> 2026-09-11 23:11:08-07:00
committergravatar for squeek502@hotmail.comRyan Liptak <squeek502@hotmail.com> 2026-09-13 00:21:00+02:00
log0db7eadccdb926e2c2aa952e66a2d46d29c3bbe9
treed7f5d8a5af42cff4a09e09ff34bec0734eb1a884
parentd84959d9e23799c4688836fbab90d3b9518fe60a

Compilation: close the linker output file before writing whole cache manifest

The issue that this fixes was previously fixed in 5e0e1841c0, but regressed in 77a4c4bbcf. This is something of a combination of both changes: - `comp.bin_file` remains non-null so the defer can run to update the progress node - Closing the file and releasing the lock has been re-introduced, which is the important bit of the `destroy()` call that was removed in 77a4c4bbcf Closes https://codeberg.org/ziglang/zig/issues/36651

1 files changed, 11 insertions(+), 0 deletions(-)

src/Compilation.zig+11
...@@ -3151,6 +3151,17 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateE...@@ -3151,6 +3151,17 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateE
3151 // cache manifest must not be written.3151 // cache manifest must not be written.
3152 if (anyErrors(comp)) return;3152 if (anyErrors(comp)) return;
31533153
3154 // Release the lock and close the file before writing the manifest.
3155 // This avoids the potential of another process getting a cache hit and
3156 // trying to spawn a process with it while there's still an open fd to it.
3157 if (comp.bin_file) |lf| {
3158 lf.releaseLock();
3159 if (lf.file) |f| {
3160 f.close(io);
3161 lf.file = null;
3162 }
3163 }
3164
3154 // Failure here only means an unnecessary cache miss.3165 // Failure here only means an unnecessary cache miss.
3155 man.writeManifest() catch |err| log.warn("failed to write cache manifest: {t}", .{err});3166 man.writeManifest() catch |err| log.warn("failed to write cache manifest: {t}", .{err});
31563167