hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

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:
Mcmd/hare/build/queue.ha | 10+++++++---
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