Skip to content

Commit 8f02110

Browse files
fix(build): a slot reported missing in its existing directory is held
On macOS an executor's first attempt on a contended slot is now and then reported "not found" though the directory and the file exist; the next attempt reports it held, and the kernel answers EAGAIN throughout (probe #895, mcpplibs/openkal-macos#45). The slot is treated as held while its directory exists, unless every round reports it for five seconds. Co-authored-by: speak-agent <248744407+speak-agent@users.noreply.github.com>
1 parent 08341b3 commit 8f02110

1 file changed

Lines changed: 17 additions & 1 deletion

File tree

‎src/build/schedule/detach_codegen.cppm‎

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -363,9 +363,10 @@ acquire_permit(const Actor& actor, const std::filesystem::path& requested, int r
363363
}
364364
const auto started = std::chrono::steady_clock::now();
365365
constexpr auto kLimit = std::chrono::hours(2);
366+
std::optional<std::chrono::steady_clock::time_point> unexplainedSince;
366367
for (;;) {
367368
if (!actor.owner.active()) return std::unexpected(130);
368-
bool orphan = false;
369+
bool orphan = false, unexplained = false;
369370
for (int i = 0; i < cap; ++i) {
370371
auto permit = mcpplibs::os::fs::lock::acquire(dir / std::format("slot-{}.lock", i),
371372
mcpplibs::os::fs::lock::kind::exclusive, false);
@@ -378,11 +379,26 @@ acquire_permit(const Actor& actor, const std::filesystem::path& requested, int r
378379
}
379380
return Permit{std::optional<mcpplibs::os::fs::lock>{std::move(*permit)},reservation};
380381
}
382+
// On macOS a slot another compiler holds is now and then reported
383+
// "not found" from inside this executor, though the directory and
384+
// the file exist and the next attempt reports it held (measured on
385+
// #889; the kernel itself answers EAGAIN, mcpplibs/openkal-macos#45).
386+
// It is treated as held while the directory exists, unless every
387+
// round reports it for five seconds.
388+
std::error_code dirError;
389+
if (permit.error().code == mcpplibs::os::errc::not_found
390+
&& std::filesystem::is_directory(dir, dirError)) { unexplained = true; continue; }
381391
if (permit.error().code != mcpplibs::os::errc::again) {
382392
std::println(std::cerr, "mcpp: {}", permit.error().message());
383393
return std::unexpected(1);
384394
}
385395
}
396+
if (!unexplained) unexplainedSince.reset();
397+
else if (!unexplainedSince) unexplainedSince = std::chrono::steady_clock::now();
398+
else if (std::chrono::steady_clock::now() - *unexplainedSince > std::chrono::seconds(5)) {
399+
std::println(std::cerr, "mcpp: the compiler slots in {} have reported themselves missing for 5s", dir.string());
400+
return std::unexpected(1);
401+
}
386402
if (orphan && std::chrono::steady_clock::now()-started > std::chrono::seconds(5)) {
387403
std::println(std::cerr,"mcpp: a previous compiler unit is occupied or unknown; its slot remains reserved");
388404
return std::unexpected(1);

0 commit comments

Comments
 (0)