authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-12-25 19:02:15-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-12-25 19:02:15-07:00
loged39ff202baf5bb73e54f7ecc20df63d9c190dc9
tree140eec25db6ef3d22599ce4f0d65d46d59903f82
parentc452bb13220b11242358f06ba80487d4148dbb27

stage2: Cache: fix resource management of the deadlock debug code


1 files changed, 34 insertions(+), 7 deletions(-)

src/Cache.zig+34-7
......@@ -19,6 +19,7 @@ var all_cache_digest_set: std.AutoHashMapUnmanaged(BinDigest, void) = .{};
1919var all_cache_digest_lock: std.Mutex = .{};
2020const want_debug_deadlock = true; // TODO change this for release builds
2121const DebugBinDigest = if (want_debug_deadlock) BinDigest else void;
22const null_debug_bin_digest = if (want_debug_deadlock) ([1]u8{0} ** bin_digest_len) else {};
2223
2324/// Be sure to call `Manifest.deinit` after successful initialization.
2425pub fn obtain(cache: *const Cache) Manifest {
......@@ -193,7 +194,7 @@ pub const Manifest = struct {
193194 manifest_dirty: bool,
194195 files: std.ArrayListUnmanaged(File) = .{},
195196 hex_digest: [hex_digest_len]u8,
196 bin_digest: DebugBinDigest = undefined,
197 debug_bin_digest: DebugBinDigest = null_debug_bin_digest,
197198
198199 /// Add a file as a dependency of process being cached. When `hit` is
199200 /// called, the file's contents will be checked to ensure that it matches
......@@ -262,7 +263,7 @@ pub const Manifest = struct {
262263 self.hash.hasher.final(&bin_digest);
263264
264265 if (want_debug_deadlock) {
265 self.bin_digest = bin_digest;
266 self.debug_bin_digest = bin_digest;
266267
267268 const held = all_cache_digest_lock.acquire();
268269 defer held.release();
......@@ -603,18 +604,27 @@ pub const Manifest = struct {
603604 /// The `Manifest` remains safe to deinit.
604605 /// Don't forget to call `writeManifest` before this!
605606 pub fn toOwnedLock(self: *Manifest) Lock {
606 const manifest_file = self.manifest_file.?;
607 self.manifest_file = null;
608 return Lock{
609 .manifest_file = manifest_file,
610 .debug_bin_digest = self.bin_digest,
607 const lock: Lock = .{
608 .manifest_file = self.manifest_file.?,
609 .debug_bin_digest = self.debug_bin_digest,
611610 };
611 self.manifest_file = null;
612 self.debug_bin_digest = null_debug_bin_digest;
613 return lock;
612614 }
613615
614616 /// Releases the manifest file and frees any memory the Manifest was using.
615617 /// `Manifest.hit` must be called first.
616618 /// Don't forget to call `writeManifest` before this!
617619 pub fn deinit(self: *Manifest) void {
620 if (want_debug_deadlock) {
621 if (!mem.eql(u8, &self.debug_bin_digest, &null_debug_bin_digest)) {
622 const held = all_cache_digest_lock.acquire();
623 defer held.release();
624
625 all_cache_digest_set.removeAssertDiscard(self.debug_bin_digest);
626 }
627 }
618628 if (self.manifest_file) |file| {
619629 file.close();
620630 }
......@@ -698,6 +708,11 @@ test "cache file and then recall it" {
698708 // https://github.com/ziglang/zig/issues/5437
699709 return error.SkipZigTest;
700710 }
711 defer if (want_debug_deadlock) {
712 testing.expect(all_cache_digest_set.count() == 0);
713 all_cache_digest_set.clearAndFree(testing.allocator);
714 };
715
701716 const cwd = fs.cwd();
702717
703718 const temp_file = "test.txt";
......@@ -775,6 +790,10 @@ test "check that changing a file makes cache fail" {
775790 // https://github.com/ziglang/zig/issues/5437
776791 return error.SkipZigTest;
777792 }
793 defer if (want_debug_deadlock) {
794 testing.expect(all_cache_digest_set.count() == 0);
795 all_cache_digest_set.clearAndFree(testing.allocator);
796 };
778797 const cwd = fs.cwd();
779798
780799 const temp_file = "cache_hash_change_file_test.txt";
......@@ -851,6 +870,10 @@ test "no file inputs" {
851870 // https://github.com/ziglang/zig/issues/5437
852871 return error.SkipZigTest;
853872 }
873 defer if (want_debug_deadlock) {
874 testing.expect(all_cache_digest_set.count() == 0);
875 all_cache_digest_set.clearAndFree(testing.allocator);
876 };
854877 const cwd = fs.cwd();
855878 const temp_manifest_dir = "no_file_inputs_manifest_dir";
856879 defer cwd.deleteTree(temp_manifest_dir) catch {};
......@@ -896,6 +919,10 @@ test "Manifest with files added after initial hash work" {
896919 // https://github.com/ziglang/zig/issues/5437
897920 return error.SkipZigTest;
898921 }
922 defer if (want_debug_deadlock) {
923 testing.expect(all_cache_digest_set.count() == 0);
924 all_cache_digest_set.clearAndFree(testing.allocator);
925 };
899926 const cwd = fs.cwd();
900927
901928 const temp_file1 = "cache_hash_post_file_test1.txt";