* Do a substitution even if --max-jobs == 0.
This commit is contained in:
		
							parent
							
								
									cff2b2a13a
								
							
						
					
					
						commit
						351bf658f9
					
				
					 2 changed files with 23 additions and 18 deletions
				
			
		| 
						 | 
					@ -186,9 +186,9 @@ private:
 | 
				
			||||||
    /* Child processes currently running. */
 | 
					    /* Child processes currently running. */
 | 
				
			||||||
    Children children;
 | 
					    Children children;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Number of build slots occupied.  Not all child processes
 | 
					    /* Number of build slots occupied.  This includes local builds and
 | 
				
			||||||
       (namely build hooks) count as occupied build slots. */
 | 
					       substitutions but not remote builds via the build hook. */
 | 
				
			||||||
    unsigned int nrChildren;
 | 
					    unsigned int nrLocalBuilds;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Maps used to prevent multiple instantiations of a goal for the
 | 
					    /* Maps used to prevent multiple instantiations of a goal for the
 | 
				
			||||||
       same derivation / path. */
 | 
					       same derivation / path. */
 | 
				
			||||||
| 
						 | 
					@ -223,8 +223,10 @@ public:
 | 
				
			||||||
    /* Wake up a goal (i.e., there is something for it to do). */
 | 
					    /* Wake up a goal (i.e., there is something for it to do). */
 | 
				
			||||||
    void wakeUp(GoalPtr goal);
 | 
					    void wakeUp(GoalPtr goal);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Can we start another child process? */
 | 
					    /* Return the number of local build and substitution processes
 | 
				
			||||||
    bool canBuildMore();
 | 
					       currently running (but not remote builds via the build
 | 
				
			||||||
 | 
					       hook). */
 | 
				
			||||||
 | 
					    unsigned int getNrLocalBuilds();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Registers a running child process.  `inBuildSlot' means that
 | 
					    /* Registers a running child process.  `inBuildSlot' means that
 | 
				
			||||||
       the process counts towards the jobs limit. */
 | 
					       the process counts towards the jobs limit. */
 | 
				
			||||||
| 
						 | 
					@ -1042,7 +1044,7 @@ void DerivationGoal::tryToBuild()
 | 
				
			||||||
    usingBuildHook = false;
 | 
					    usingBuildHook = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Make sure that we are allowed to start a build. */
 | 
					    /* Make sure that we are allowed to start a build. */
 | 
				
			||||||
    if (!worker.canBuildMore()) {
 | 
					    if (worker.getNrLocalBuilds() >= maxBuildJobs) {
 | 
				
			||||||
        worker.waitForBuildSlot(shared_from_this());
 | 
					        worker.waitForBuildSlot(shared_from_this());
 | 
				
			||||||
        outputLocks.unlock();
 | 
					        outputLocks.unlock();
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
| 
						 | 
					@ -1232,7 +1234,7 @@ DerivationGoal::HookReply DerivationGoal::tryBuildHook()
 | 
				
			||||||
                throw SysError("setting an environment variable");
 | 
					                throw SysError("setting an environment variable");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            execl(buildHook.c_str(), buildHook.c_str(),
 | 
					            execl(buildHook.c_str(), buildHook.c_str(),
 | 
				
			||||||
                (worker.canBuildMore() ? (string) "1" : "0").c_str(),
 | 
					                (worker.getNrLocalBuilds() < maxBuildJobs ? (string) "1" : "0").c_str(),
 | 
				
			||||||
                thisSystem.c_str(),
 | 
					                thisSystem.c_str(),
 | 
				
			||||||
                drv.platform.c_str(),
 | 
					                drv.platform.c_str(),
 | 
				
			||||||
                drvPath.c_str(),
 | 
					                drvPath.c_str(),
 | 
				
			||||||
| 
						 | 
					@ -2170,7 +2172,7 @@ void SubstitutionGoal::referencesValid()
 | 
				
			||||||
            assert(worker.store.isValidPath(*i));
 | 
					            assert(worker.store.isValidPath(*i));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    state = &SubstitutionGoal::tryToRun;
 | 
					    state = &SubstitutionGoal::tryToRun;
 | 
				
			||||||
    worker.waitForBuildSlot(shared_from_this());
 | 
					    worker.wakeUp(shared_from_this());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2178,8 +2180,11 @@ void SubstitutionGoal::tryToRun()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    trace("trying to run");
 | 
					    trace("trying to run");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Make sure that we are allowed to start a build. */
 | 
					    /* Make sure that we are allowed to start a build.  Note that even
 | 
				
			||||||
    if (!worker.canBuildMore()) {
 | 
					       is maxBuildJobs == 0 (no local builds allowed), we still allow
 | 
				
			||||||
 | 
					       a substituter to run.  This is because substitutions cannot be
 | 
				
			||||||
 | 
					       distributed to another machine via the build hook. */
 | 
				
			||||||
 | 
					    if (worker.getNrLocalBuilds() >= (maxBuildJobs == 0 ? 1 : maxBuildJobs)) {
 | 
				
			||||||
        worker.waitForBuildSlot(shared_from_this());
 | 
					        worker.waitForBuildSlot(shared_from_this());
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -2362,7 +2367,7 @@ Worker::Worker(LocalStore & store)
 | 
				
			||||||
    /* Debugging: prevent recursive workers. */ 
 | 
					    /* Debugging: prevent recursive workers. */ 
 | 
				
			||||||
    if (working) abort();
 | 
					    if (working) abort();
 | 
				
			||||||
    working = true;
 | 
					    working = true;
 | 
				
			||||||
    nrChildren = 0;
 | 
					    nrLocalBuilds = 0;
 | 
				
			||||||
    lastWokenUp = 0;
 | 
					    lastWokenUp = 0;
 | 
				
			||||||
    cacheFailure = queryBoolSetting("build-cache-failure", false);
 | 
					    cacheFailure = queryBoolSetting("build-cache-failure", false);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -2449,9 +2454,9 @@ void Worker::wakeUp(GoalPtr goal)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool Worker::canBuildMore()
 | 
					unsigned Worker::getNrLocalBuilds()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return nrChildren < maxBuildJobs;
 | 
					    return nrLocalBuilds;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2464,7 +2469,7 @@ void Worker::childStarted(GoalPtr goal,
 | 
				
			||||||
    child.lastOutput = time(0);
 | 
					    child.lastOutput = time(0);
 | 
				
			||||||
    child.inBuildSlot = inBuildSlot;
 | 
					    child.inBuildSlot = inBuildSlot;
 | 
				
			||||||
    children[pid] = child;
 | 
					    children[pid] = child;
 | 
				
			||||||
    if (inBuildSlot) nrChildren++;
 | 
					    if (inBuildSlot) nrLocalBuilds++;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2476,8 +2481,8 @@ void Worker::childTerminated(pid_t pid, bool wakeSleepers)
 | 
				
			||||||
    assert(i != children.end());
 | 
					    assert(i != children.end());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (i->second.inBuildSlot) {
 | 
					    if (i->second.inBuildSlot) {
 | 
				
			||||||
        assert(nrChildren > 0);
 | 
					        assert(nrLocalBuilds > 0);
 | 
				
			||||||
        nrChildren--;
 | 
					        nrLocalBuilds--;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    children.erase(pid);
 | 
					    children.erase(pid);
 | 
				
			||||||
| 
						 | 
					@ -2500,7 +2505,7 @@ void Worker::childTerminated(pid_t pid, bool wakeSleepers)
 | 
				
			||||||
void Worker::waitForBuildSlot(GoalPtr goal)
 | 
					void Worker::waitForBuildSlot(GoalPtr goal)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    debug("wait for build slot");
 | 
					    debug("wait for build slot");
 | 
				
			||||||
    if (canBuildMore())
 | 
					    if (getNrLocalBuilds() < maxBuildJobs)
 | 
				
			||||||
        wakeUp(goal); /* we can do it right away */
 | 
					        wakeUp(goal); /* we can do it right away */
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
        wantingToBuild.insert(goal);
 | 
					        wantingToBuild.insert(goal);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,7 +15,7 @@ echo $outPath > $TEST_ROOT/sub-paths
 | 
				
			||||||
# First try a substituter that fails, then one that succeeds
 | 
					# First try a substituter that fails, then one that succeeds
 | 
				
			||||||
export NIX_SUBSTITUTERS=$(pwd)/substituter2.sh:$(pwd)/substituter.sh
 | 
					export NIX_SUBSTITUTERS=$(pwd)/substituter2.sh:$(pwd)/substituter.sh
 | 
				
			||||||
 | 
					
 | 
				
			||||||
$nixstore -rvv "$drvPath"
 | 
					$nixstore -j0 -rvv "$drvPath"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
text=$(cat "$outPath"/hello)
 | 
					text=$(cat "$outPath"/hello)
 | 
				
			||||||
if test "$text" != "Hallo Wereld"; then echo "wrong substitute output: $text"; exit 1; fi
 | 
					if test "$text" != "Hallo Wereld"; then echo "wrong substitute output: $text"; exit 1; fi
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue