diff options
author | Eelco Dolstra <e.dolstra@tudelft.nl> | 2004-01-15T20·23+0000 |
---|---|---|
committer | Eelco Dolstra <e.dolstra@tudelft.nl> | 2004-01-15T20·23+0000 |
commit | 447089a5f699f085661287dec4b3d88219f67068 (patch) | |
tree | e460c615181db3e6b6f8b48e4e934b372ecac043 /src/libstore/normalise.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/normalise.cc')
-rw-r--r-- | src/libstore/normalise.cc | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/src/libstore/normalise.cc b/src/libstore/normalise.cc index 7ef45e292352..51f90207ead3 100644 --- a/src/libstore/normalise.cc +++ b/src/libstore/normalise.cc @@ -96,6 +96,7 @@ Path normaliseStoreExpr(const Path & _nePath, PathSet pending) for (PathSet::iterator i = ne.derivation.inputs.begin(); i != ne.derivation.inputs.end(); i++) { + checkInterrupt(); Path nfPath = normaliseStoreExpr(*i, pending); realiseClosure(nfPath, pending); /* !!! nfPath should be a root of the garbage collector while @@ -193,6 +194,7 @@ Path normaliseStoreExpr(const Path & _nePath, PathSet pending) for (Paths::iterator j = refPaths.begin(); j != refPaths.end(); j++) { + checkInterrupt(); Path path = *j; elem.refs.insert(path); if (inClosures.find(path) != inClosures.end()) @@ -209,6 +211,7 @@ Path normaliseStoreExpr(const Path & _nePath, PathSet pending) PathSet donePaths; while (!usedPaths.empty()) { + checkInterrupt(); PathSet::iterator i = usedPaths.begin(); Path path = *i; usedPaths.erase(i); @@ -291,6 +294,7 @@ void ensurePath(const Path & path, PathSet pending) for (Paths::iterator i = subPaths.begin(); i != subPaths.end(); i++) { + checkInterrupt(); try { normaliseStoreExpr(*i, pending); if (isValidPath(path)) return; @@ -337,6 +341,8 @@ static void requisitesWorker(const Path & nePath, bool includeExprs, bool includeSuccessors, PathSet & paths, PathSet & doneSet) { + checkInterrupt(); + if (doneSet.find(nePath) != doneSet.end()) return; doneSet.insert(nePath); |