Merge pull request #14998 from NixOS/fix-remote-store-nar-from-path
libstore: Do not mark connections as bad when RemoteStore::narFromPath is called as a coroutine
This commit is contained in:
@@ -58,8 +58,13 @@ RemoteStore::RemoteStore(const Config & config)
|
||||
|
||||
ref<RemoteStore::Connection> RemoteStore::openConnectionWrapper()
|
||||
{
|
||||
if (failed)
|
||||
if (failed) {
|
||||
checkInterrupt();
|
||||
/* Throw Interrupted instead of the following error to silence pesky
|
||||
warning messages that ThreadPool prints on shutdown if other threads
|
||||
failed. */
|
||||
throw Error("opening a connection to remote store '%s' previously failed", config.getHumanReadableURI());
|
||||
}
|
||||
try {
|
||||
return openConnection();
|
||||
} catch (...) {
|
||||
|
||||
@@ -44,8 +44,8 @@ public:
|
||||
void operator=(AutoCloseFD pid);
|
||||
#endif
|
||||
~Pid();
|
||||
int kill();
|
||||
int wait();
|
||||
int kill(bool allowInterrupts = true);
|
||||
int wait(bool allowInterrupts = true);
|
||||
|
||||
// TODO: Implement for Windows
|
||||
#ifndef _WIN32
|
||||
|
||||
@@ -412,7 +412,7 @@ std::unique_ptr<Source> sinkToSource(std::function<void(Sink &)> fun, std::funct
|
||||
}
|
||||
|
||||
if (cur.empty()) {
|
||||
if (hasCoro) {
|
||||
if (hasCoro && *coro) {
|
||||
(*coro)();
|
||||
}
|
||||
if (*coro) {
|
||||
@@ -427,6 +427,16 @@ std::unique_ptr<Source> sinkToSource(std::function<void(Sink &)> fun, std::funct
|
||||
size_t n = cur.copy(data, len);
|
||||
cur.remove_prefix(n);
|
||||
|
||||
/* This is necessary to ensure that the coroutine gets resumed
|
||||
after the consumer has finished reading the Source. Otherwise the
|
||||
coroutine is always abandoned (i.e. it is always destroyed when
|
||||
suspended). */
|
||||
if (cur.empty() && coro && *coro) {
|
||||
(*coro)();
|
||||
if (*coro)
|
||||
cur = coro->get();
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -41,9 +41,11 @@ Pid::Pid(pid_t pid)
|
||||
}
|
||||
|
||||
Pid::~Pid()
|
||||
{
|
||||
try {
|
||||
if (pid != -1)
|
||||
kill();
|
||||
kill(/*allowInterrupts=*/false);
|
||||
} catch (...) {
|
||||
ignoreExceptionInDestructor();
|
||||
}
|
||||
|
||||
void Pid::operator=(pid_t pid)
|
||||
@@ -59,7 +61,7 @@ Pid::operator pid_t()
|
||||
return pid;
|
||||
}
|
||||
|
||||
int Pid::kill()
|
||||
int Pid::kill(bool allowInterrupts)
|
||||
{
|
||||
assert(pid != -1);
|
||||
|
||||
@@ -78,10 +80,10 @@ int Pid::kill()
|
||||
logError(SysError("killing process %d", pid).info());
|
||||
}
|
||||
|
||||
return wait();
|
||||
return wait(allowInterrupts);
|
||||
}
|
||||
|
||||
int Pid::wait()
|
||||
int Pid::wait(bool allowInterrupts)
|
||||
{
|
||||
assert(pid != -1);
|
||||
while (1) {
|
||||
@@ -93,7 +95,8 @@ int Pid::wait()
|
||||
}
|
||||
if (errno != EINTR)
|
||||
throw SysError("cannot get exit status of PID %d", pid);
|
||||
checkInterrupt();
|
||||
if (allowInterrupts)
|
||||
checkInterrupt();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user