aboutsummaryrefslogtreecommitdiff
path: root/src/libstore/build.cc
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2011-06-30 15:19:13 +0000
committerLudovic Courtès <ludo@gnu.org>2011-06-30 15:19:13 +0000
commit5c9e9f732df6d95d712f25de9880b7461c53d6ca (patch)
treed4e562f7048f57d0ec87461bce441dfd450374f7 /src/libstore/build.cc
parent9c99aa2620b8f86c0e7f99ebfe868e8ccb306f71 (diff)
Add support for the `build-timeout' and `--timeout' options.
Diffstat (limited to 'src/libstore/build.cc')
-rw-r--r--src/libstore/build.cc34
1 files changed, 30 insertions, 4 deletions
diff --git a/src/libstore/build.cc b/src/libstore/build.cc
index 83bd6754a..4df62acea 100644
--- a/src/libstore/build.cc
+++ b/src/libstore/build.cc
@@ -209,7 +209,10 @@ private:
/* Last time the goals in `waitingForAWhile' where woken up. */
time_t lastWokenUp;
-
+
+ /* Last time `waitForInput' was last called. */
+ time_t lastWait;
+
public:
bool cacheFailure;
@@ -681,7 +684,8 @@ HookInstance::HookInstance()
builderOut.readSide.close();
if (dup2(builderOut.writeSide, 4) == -1)
throw SysError("dupping builder's stdout/stderr");
-
+
+ /* XXX: Pass `buildTimeout' to the hook? */
execl(buildHook.c_str(), buildHook.c_str(), thisSystem.c_str(),
(format("%1%") % maxSilentTime).str().c_str(),
(format("%1%") % printBuildTrace).str().c_str(),
@@ -2666,7 +2670,14 @@ void Worker::waitForInput()
struct timeval timeout;
timeout.tv_usec = 0;
time_t before = time(0);
-
+
+ /* If a global timeout has been set, sleep until it's done. */
+ if (buildTimeout != 0) {
+ useTimeout = true;
+ if (lastWait == 0 || lastWait > before) lastWait = before;
+ timeout.tv_sec = std::max((time_t) 0, lastWait + buildTimeout - before);
+ }
+
/* If we're monitoring for silence on stdout/stderr, sleep until
the first deadline for any child. */
if (maxSilentTime != 0) {
@@ -2678,8 +2689,11 @@ void Worker::waitForInput()
}
}
if (oldest) {
+ time_t silenceTimeout = std::max((time_t) 0, oldest + maxSilentTime - before);
+ timeout.tv_sec = useTimeout
+ ? std::min(silenceTimeout, timeout.tv_sec)
+ : silenceTimeout;
useTimeout = true;
- timeout.tv_sec = std::max((time_t) 0, oldest + maxSilentTime - before);
printMsg(lvlVomit, format("sleeping %1% seconds") % timeout.tv_sec);
}
}
@@ -2717,6 +2731,9 @@ void Worker::waitForInput()
time_t after = time(0);
+ /* Keep track of when we were last called. */
+ lastWait = after;
+
/* Process all available file descriptors. */
/* Since goals may be canceled from inside the loop below (causing
@@ -2765,6 +2782,15 @@ void Worker::waitForInput()
% goal->getName() % maxSilentTime);
goal->cancel();
}
+
+ if (buildTimeout != 0 &&
+ after - before >= (time_t) buildTimeout)
+ {
+ printMsg(lvlError,
+ format("%1% timed out after %2% seconds of activity")
+ % goal->getName() % buildTimeout);
+ goal->cancel();
+ }
}
if (!waitingForAWhile.empty() && lastWokenUp + wakeUpInterval <= after) {