diff options
author | Eelco Dolstra <e.dolstra@tudelft.nl> | 2004-01-15 20:23:55 +0000 |
---|---|---|
committer | Eelco Dolstra <e.dolstra@tudelft.nl> | 2004-01-15 20:23:55 +0000 |
commit | 447089a5f699f085661287dec4b3d88219f67068 (patch) | |
tree | e460c615181db3e6b6f8b48e4e934b372ecac043 /src/libstore/pathlocks.cc | |
parent | 08719c6c97e25fb362eeb7463d8b764ecefc53cb (diff) |
* Catch SIGINT to terminate cleanly when the user tries to interrupt
Nix. This is to prevent Berkeley DB from becoming wedged.
Unfortunately it is not possible to throw C++ exceptions from a
signal handler. In fact, you can't do much of anything except
change variables of type `volatile sig_atomic_t'. So we set an
interrupt flag in the signal handler and check it at various
strategic locations in the code (by calling checkInterrupt()).
Since this is unlikely to cover all cases (e.g., (semi-)infinite
loops), sometimes SIGTERM may now be required to kill Nix.
Diffstat (limited to 'src/libstore/pathlocks.cc')
-rw-r--r-- | src/libstore/pathlocks.cc | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/src/libstore/pathlocks.cc b/src/libstore/pathlocks.cc index 321e965bb..d4f980c64 100644 --- a/src/libstore/pathlocks.cc +++ b/src/libstore/pathlocks.cc @@ -19,11 +19,14 @@ bool lockFile(int fd, LockType lockType, bool wait) lock.l_len = 0; /* entire file */ if (wait) { - while (fcntl(fd, F_SETLKW, &lock) != 0) + while (fcntl(fd, F_SETLKW, &lock) != 0) { + checkInterrupt(); if (errno != EINTR) throw SysError(format("acquiring/releasing lock")); + } } else { while (fcntl(fd, F_SETLK, &lock) != 0) { + checkInterrupt(); if (errno == EACCES || errno == EAGAIN) return false; if (errno != EINTR) throw SysError(format("acquiring/releasing lock")); @@ -55,6 +58,7 @@ PathLocks::PathLocks(const PathSet & _paths) /* Acquire the lock for each path. */ for (Paths::iterator i = paths.begin(); i != paths.end(); i++) { + checkInterrupt(); Path path = *i; Path lockPath = path + ".lock"; @@ -87,6 +91,7 @@ PathLocks::~PathLocks() close(*i); for (Paths::iterator i = paths.begin(); i != paths.end(); i++) { + checkInterrupt(); if (deletePaths) { /* This is not safe in general! */ unlink(i->c_str()); |