commit 66c9d4082b6273e673cd78e8f8cb19d8f6ad386b
parent 267d488f73451731eed05076fdcd008f59be67a1
Author: Alexey Yerin <yyp@disroot.org>
Date: Fri, 8 Sep 2023 22:59:19 +0300
cmd/hare: Rename the temporary file after writing typedefs
Running multiple build drivers in parallel should no longer cause
"expected non-void prefix in get_cache()" assertion failures.
While renaming a file might not seem like it would release a lock, that's what
it does. The build driver does not hold a reference to a file when re-trying to
lock it and just uses a path. When a file is moved, there would be nothing at
the original path, so the file is created and will be treated as unlocked.
That's not a problem for most cache types, but stage::SSA also writes a
typedef pointer to <out>.td, yet it does so *after* the lock is released by
renaming. This violates the expectation that the cache is ready after lock is
released - there are no typedefs yet. get_td is happy and just ignores the
error, but then a hash is not written into ctx.hashes, which later causes an
assertion failure in get_cache.
Signed-off-by: Alexey Yerin <yyp@disroot.org>
Diffstat:
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/cmd/hare/build/queue.ha b/cmd/hare/build/queue.ha
@@ -222,13 +222,17 @@ fn await_task(ctx: *context, jobs: *[]job) (size | void | error) = {
fn cleanup_task(ctx: *context, t: *task) (void | error) = {
let out = get_cache(ctx, t.idx, t.kind)?;
defer free(out);
+
+ if (t.kind == stage::SSA) {
+ cleanup_ssa_task(ctx, t, out)?;
+ };
+
let tmp = strings::concat(out, ".tmp");
defer free(tmp);
os::move(tmp, out)?;
- if (t.kind != stage::SSA) {
- return;
- };
+};
+fn cleanup_ssa_task(ctx: *context, t: *task, out: str) (void | error) = {
// td file is hashed solely based on its contents. not worth doing this
// for other types of outputs, but it gets us better caching behavior
// for tds since we need to include the dependency tds in the ssa hash