authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-08-12 21:52:32-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-08-13 11:32:46+02:00
loga68b5ee372365034289308967ff488b194aa9fa9
treee464582ce80e7fdeea5256e3f25e1a4e64b09ebb
parent2e77ff7ca9c25a262969cf55992d0bf2ecaa483d

std.Build.Cache: introduce API for taking the files

ability to take ownership of the set of input files prior to deinitializing a Manifest

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

lib/std/Build/Cache.zig+22-11
...@@ -1,7 +1,7 @@...@@ -1,7 +1,7 @@
1//! Manages `zig-cache` directories.1//! Tracks metadata of file inputs associated with Zig compiler and build
2//! This is not a general-purpose cache. It is designed to be fast and simple,2//! system artifacts in order to determine whether those artifacts must be
3//! not to withstand attacks using specially-crafted input.3//! produced again, or may be retrieved from the cache directory on the
44//! filesystem.
5const Cache = @This();5const Cache = @This();
6const builtin = @import("builtin");6const builtin = @import("builtin");
77
...@@ -1236,19 +1236,32 @@ pub const Manifest = struct {...@@ -1236,19 +1236,32 @@ pub const Manifest = struct {
12361236
1237 /// Obtain only the data needed to maintain a lock on the manifest file.1237 /// Obtain only the data needed to maintain a lock on the manifest file.
1238 /// The `Manifest` remains safe to deinit.1238 /// The `Manifest` remains safe to deinit.
1239 ///
1239 /// Don't forget to call `writeManifest` before this!1240 /// Don't forget to call `writeManifest` before this!
1240 pub fn toOwnedLock(self: *Manifest) Lock {1241 pub fn toOwnedLock(self: *Manifest) Lock {
1241 defer self.manifest_file = null;1242 defer self.manifest_file = null;
1242 return .{ .manifest_file = self.manifest_file.? };1243 return .{ .manifest_file = self.manifest_file.? };
1243 }1244 }
12441245
1246 pub fn takeFiles(man: *Manifest) Files {
1247 defer man.files = .empty;
1248 return man.files;
1249 }
1250
1251 pub fn freeFiles(gpa: Allocator, files: *Files) void {
1252 for (files.keys()) |*file| file.deinit(gpa);
1253 files.deinit(gpa);
1254 }
1255
1245 /// Releases the manifest file and frees any memory the Manifest was using.1256 /// Releases the manifest file and frees any memory the Manifest was using.
1246 /// `Manifest.hit` must be called first.1257 /// `Manifest.hit` must be called first.
1258 ///
1247 /// Don't forget to call `writeManifest` before this!1259 /// Don't forget to call `writeManifest` before this!
1248 pub fn deinit(self: *Manifest) void {1260 pub fn deinit(man: *Manifest) void {
1249 const io = self.cache.io;1261 const io = man.cache.io;
1262 const gpa = man.cache.gpa;
12501263
1251 if (self.manifest_file) |file| {1264 if (man.manifest_file) |file| {
1252 if (builtin.os.tag == .windows) {1265 if (builtin.os.tag == .windows) {
1253 // See Lock.release for why this is required on Windows1266 // See Lock.release for why this is required on Windows
1254 file.unlock(io);1267 file.unlock(io);
...@@ -1256,10 +1269,8 @@ pub const Manifest = struct {...@@ -1256,10 +1269,8 @@ pub const Manifest = struct {
12561269
1257 file.close(io);1270 file.close(io);
1258 }1271 }
1259 for (self.files.keys()) |*file| {1272 freeFiles(gpa, &man.files);
1260 file.deinit(self.cache.gpa);1273 man.* = undefined;
1261 }
1262 self.files.deinit(self.cache.gpa);
1263 }1274 }
12641275
1265 pub fn populateFileSystemInputs(man: *Manifest, buf: *std.ArrayList(u8)) Allocator.Error!void {1276 pub fn populateFileSystemInputs(man: *Manifest, buf: *std.ArrayList(u8)) Allocator.Error!void {