diff --git a/lix/libexpr/eval.cc b/lix/libexpr/eval.cc index 4303e4b70..232614be1 100644 --- a/lix/libexpr/eval.cc +++ b/lix/libexpr/eval.cc @@ -4,6 +4,7 @@ #include "lix/libutil/archive.hh" #include "lix/libutil/ansicolor.hh" #include "lix/libutil/async.hh" +#include "lix/libutil/current-process.hh" #include "lix/libutil/deprecated-features.hh" #include "lix/libutil/error.hh" #include "lix/libutil/english.hh" @@ -391,6 +392,11 @@ Evaluator::Evaluator( box_ptr Evaluator::begin(AsyncIoRoot & aio) { assert(!activeEval); + + // Increase the default stack size for the evaluator and for + // libstdc++'s std::regex. + ensureStackSizeAtLeast(64ul * 1024 * 1024); + return box_ptr::unsafeFromNonnull( std::unique_ptr(new EvalState(aio, *this)) ); diff --git a/lix/libutil/current-process.cc b/lix/libutil/current-process.cc index 0c9df5b89..816f96061 100644 --- a/lix/libutil/current-process.cc +++ b/lix/libutil/current-process.cc @@ -54,8 +54,12 @@ unsigned int getMaxCPU() rlim_t savedStackSize = 0; -void setStackSize(rlim_t stackSize) +void ensureStackSizeAtLeast(rlim_t stackSize) { + if (savedStackSize >= stackSize) { + return; + } + struct rlimit limit; if (getrlimit(RLIMIT_STACK, &limit) == 0 && limit.rlim_cur < stackSize) { savedStackSize = limit.rlim_cur; diff --git a/lix/libutil/current-process.hh b/lix/libutil/current-process.hh index 316af234e..42c952de9 100644 --- a/lix/libutil/current-process.hh +++ b/lix/libutil/current-process.hh @@ -14,12 +14,10 @@ namespace nix { */ unsigned int getMaxCPU(); - /** - * Change the stack size. + * Increase the stack size rlimit if it is currently smaller than `stackSize`. */ -void setStackSize(rlim_t stackSize); - +void ensureStackSizeAtLeast(rlim_t stackSize); /** * Restore the original inherited Unix process context (such as signal diff --git a/lix/nix/main.cc b/lix/nix/main.cc index 77e38ee97..3057ff223 100644 --- a/lix/nix/main.cc +++ b/lix/nix/main.cc @@ -665,10 +665,6 @@ int main(int argc, char * * argv) std::abort(); } - // Increase the default stack size for the evaluator and for - // libstdc++'s std::regex. - nix::setStackSize(64ul * 1024 * 1024); - return nix::handleExceptions(argv[0], [&]() { nix::AsyncIoRoot aio; return nix::mainWrapped(aio, argc, argv); diff --git a/subprojects/nix-eval-jobs/src/worker.cc b/subprojects/nix-eval-jobs/src/worker.cc index 29db4fa89..9910a1db2 100644 --- a/subprojects/nix-eval-jobs/src/worker.cc +++ b/subprojects/nix-eval-jobs/src/worker.cc @@ -127,7 +127,7 @@ void worker(nix::AutoCloseFD &to, nix::AutoCloseFD &from, MyArgs &args) try { // Increase the default stack size for the evaluator and for // libstdc++'s std::regex. - nix::setStackSize(64 * 1024 * 1024); + nix::ensureStackSizeAtLeast(64 * 1024 * 1024); #if HAVE_BOEHMGC // We are doing the garbage collection by killing forks.