* While waiting for a lock, print a sign of life every 5 minutes.
This prevents remote builders from being killed by the `max-silent-time' inactivity monitor while they are waiting for a long garbage collection to finish. This happens fairly often in the Hydra build farm.
This commit is contained in:
parent
c45de33c67
commit
f859a8d3c3
3 changed files with 27 additions and 3 deletions
|
@ -31,6 +31,11 @@ static void sigintHandler(int signo)
|
|||
}
|
||||
|
||||
|
||||
static void sigalrmHandler(int signo)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Path makeRootName(const Path & gcRoot, int & counter)
|
||||
{
|
||||
counter++;
|
||||
|
@ -160,6 +165,14 @@ static void initAndRun(int argc, char * * argv)
|
|||
if (sigaction(SIGPIPE, &act, 0))
|
||||
throw SysError("ignoring SIGPIPE");
|
||||
|
||||
/* Catch SIGALRM with an empty handler (we just need it to get an
|
||||
EINTR from blocking system calls). */
|
||||
act.sa_handler = sigalrmHandler;
|
||||
sigfillset(&act.sa_mask);
|
||||
act.sa_flags = 0;
|
||||
if (sigaction(SIGALRM, &act, 0))
|
||||
throw SysError("installing handler for SIGALRM");
|
||||
|
||||
/* Reset SIGCHLD to its default. */
|
||||
act.sa_handler = SIG_DFL;
|
||||
act.sa_flags = 0;
|
||||
|
|
|
@ -37,7 +37,8 @@ void deleteLockFile(const Path & path, int fd)
|
|||
}
|
||||
|
||||
|
||||
bool lockFile(int fd, LockType lockType, bool wait)
|
||||
bool lockFile(int fd, LockType lockType, bool wait,
|
||||
unsigned int progressInterval)
|
||||
{
|
||||
struct flock lock;
|
||||
if (lockType == ltRead) lock.l_type = F_RDLCK;
|
||||
|
@ -49,11 +50,20 @@ bool lockFile(int fd, LockType lockType, bool wait)
|
|||
lock.l_len = 0; /* entire file */
|
||||
|
||||
if (wait) {
|
||||
while (fcntl(fd, F_SETLKW, &lock) != 0) {
|
||||
/* Wait until we acquire the lock. If `progressInterval' is
|
||||
non-zero, when print a message every `progressInterval'
|
||||
seconds. This is mostly to make sure that remote builders
|
||||
aren't killed due to the `max-silent-time' inactivity
|
||||
monitor while waiting for the garbage collector lock. */
|
||||
while (1) {
|
||||
if (progressInterval) alarm(progressInterval);
|
||||
if (fcntl(fd, F_SETLKW, &lock) == 0) break;
|
||||
checkInterrupt();
|
||||
if (errno != EINTR)
|
||||
throw SysError(format("acquiring/releasing lock"));
|
||||
if (progressInterval) printMsg(lvlError, "still waiting for lock...");
|
||||
}
|
||||
alarm(0);
|
||||
} else {
|
||||
while (fcntl(fd, F_SETLK, &lock) != 0) {
|
||||
checkInterrupt();
|
||||
|
|
|
@ -17,7 +17,8 @@ void deleteLockFile(const Path & path, int fd);
|
|||
|
||||
enum LockType { ltRead, ltWrite, ltNone };
|
||||
|
||||
bool lockFile(int fd, LockType lockType, bool wait);
|
||||
bool lockFile(int fd, LockType lockType, bool wait,
|
||||
unsigned int progressInterval = 300);
|
||||
|
||||
|
||||
class PathLocks
|
||||
|
|
Loading…
Reference in a new issue