Use vfork() instead of fork() if available

Hopefully this reduces the chance of hitting ‘unable to fork: Cannot
allocate memory’ errors.  vfork() is used for everything except
starting builders.
This commit is contained in:
Eelco Dolstra 2012-11-09 18:00:33 +01:00
parent 48c19c4633
commit ea89df2b76
6 changed files with 51 additions and 22 deletions

View file

@ -202,6 +202,7 @@ void checkStoreNotSymlink()
LocalStore::LocalStore(bool reserveSpace)
: didSetSubstituterEnv(false)
{
schemaPath = settings.nixDBPath + "/schema";
@ -943,6 +944,18 @@ Path LocalStore::queryPathFromHashPart(const string & hashPart)
}
void LocalStore::setSubstituterEnv()
{
if (didSetSubstituterEnv) return;
/* Pass configuration options (including those overriden with
--option) to substituters. */
setenv("_NIX_OPTIONS", settings.pack().c_str(), 1);
didSetSubstituterEnv = true;
}
void LocalStore::startSubstituter(const Path & substituter, RunningSubstituter & run)
{
if (run.pid != -1) return;
@ -955,7 +968,9 @@ void LocalStore::startSubstituter(const Path & substituter, RunningSubstituter &
fromPipe.create();
errorPipe.create();
run.pid = fork();
setSubstituterEnv();
run.pid = maybeVfork();
switch (run.pid) {
@ -964,10 +979,6 @@ void LocalStore::startSubstituter(const Path & substituter, RunningSubstituter &
case 0: /* child */
try {
/* Pass configuration options (including those overriden
with --option) to the substituter. */
setenv("_NIX_OPTIONS", settings.pack().c_str(), 1);
if (dup2(toPipe.readSide, STDIN_FILENO) == -1)
throw SysError("dupping stdin");
if (dup2(fromPipe.writeSide, STDOUT_FILENO) == -1)