From 45983abe664be648b513202c8c12578c9a85784f Mon Sep 17 00:00:00 2001 From: Roland Reichwein Date: Fri, 3 May 2024 21:03:06 +0200 Subject: Parallel build --- ProcessRunner.cpp | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 ProcessRunner.cpp (limited to 'ProcessRunner.cpp') diff --git a/ProcessRunner.cpp b/ProcessRunner.cpp new file mode 100644 index 0000000..bdde054 --- /dev/null +++ b/ProcessRunner.cpp @@ -0,0 +1,92 @@ +#include "ProcessRunner.h" + +#include +#include + +#include + +#include + +namespace bp = boost::process; + +ProcessRunner::ProcessRunner(): + _max_number_of_processes{static_cast(std::thread::hardware_concurrency())} +{} + +void ProcessRunner::spawn(const std::string& key, const std::string& command) +{ + _processes.emplace_back(process{key, command}); +} + +bool ProcessRunner::empty() +{ + return running() == 0; +} + +bool ProcessRunner::full() +{ + return running() == _max_number_of_processes; +} + +int ProcessRunner::wait_one(std::string& key) +{ + if (running() > 0 && finished() == 0) { + waitpid(-1, NULL, 0); + } + + // Actually, several childs may have finished. Therefore, end and + // remove all finished childs. + if (finished() > 0) { + for (auto it = _processes.begin(); it != _processes.end(); ++it) { + bp::child &child{it->child}; + if (!child.running()) { + child.wait(); + int result{child.exit_code()}; + + key = it->key; + + _processes.erase(it, it+1); + return result; + } + } + }; + + if (_processes.empty()) { + throw std::runtime_error("No process to wait for"); + } + + throw std::runtime_error("No process finished"); +} + +int ProcessRunner::wait_all() +{ + int ret{}; + for (auto &i: _processes) { + i.child.wait(); + int result{i.child.exit_code()}; + if (result != 0 && ret == 0) { + ret = result; + } + } + + _processes.clear(); + + return ret; +} + +size_t ProcessRunner::running() +{ + size_t result{}; + for (auto &i: _processes) { + if (i.child.running()) { + ++result; + } + } + return result; +} + +size_t ProcessRunner::finished() +{ + return _processes.size() - running(); +} + -- cgit v1.2.3