* 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:
Eelco Dolstra 2010-02-03 21:22:57 +00:00
parent c45de33c67
commit f859a8d3c3
3 changed files with 27 additions and 3 deletions

View File

@ -31,6 +31,11 @@ static void sigintHandler(int signo)
} }
static void sigalrmHandler(int signo)
{
}
Path makeRootName(const Path & gcRoot, int & counter) Path makeRootName(const Path & gcRoot, int & counter)
{ {
counter++; counter++;
@ -160,6 +165,14 @@ static void initAndRun(int argc, char * * argv)
if (sigaction(SIGPIPE, &act, 0)) if (sigaction(SIGPIPE, &act, 0))
throw SysError("ignoring SIGPIPE"); 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. */ /* Reset SIGCHLD to its default. */
act.sa_handler = SIG_DFL; act.sa_handler = SIG_DFL;
act.sa_flags = 0; act.sa_flags = 0;

View File

@ -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; struct flock lock;
if (lockType == ltRead) lock.l_type = F_RDLCK; 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 */ lock.l_len = 0; /* entire file */
if (wait) { 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(); checkInterrupt();
if (errno != EINTR) if (errno != EINTR)
throw SysError(format("acquiring/releasing lock")); throw SysError(format("acquiring/releasing lock"));
if (progressInterval) printMsg(lvlError, "still waiting for lock...");
} }
alarm(0);
} else { } else {
while (fcntl(fd, F_SETLK, &lock) != 0) { while (fcntl(fd, F_SETLK, &lock) != 0) {
checkInterrupt(); checkInterrupt();

View File

@ -17,7 +17,8 @@ void deleteLockFile(const Path & path, int fd);
enum LockType { ltRead, ltWrite, ltNone }; 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 class PathLocks