23#include <sys/socket.h>
26#include <unordered_set>
29namespace MultiProcess {
108 printf(
"fork returned with error number %d, retrying after 1 second...\n",
errno);
112 printf(
"fork returned with error number %d\n",
errno);
113 throw std::runtime_error(
"fork returned with error 3 times, aborting!");
129 throw std::runtime_error(std::string(
"ProcessManager: could not set FD_CLOEXEC: ") +
strerror(
errno));
136 throw std::runtime_error(std::string(
"ProcessManager: socketpair failed: ") +
strerror(
errno));
144 for (
int &fd :
fds) {
145 if (fd >= 0 && fd !=
keep) {
155 throw std::logic_error(
"ProcessManager: channel file descriptor already claimed or not owned by this process");
172 for (std::size_t ix = 0; ix <
N_workers_; ++ix) {
181 for (std::size_t ix = 0; ix <
N_workers_; ++ix) {
246 for (std::size_t ix = 0; ix <
N_workers_; ++ix) {
281 std::perror(
"pipe failed");
287 std::perror(
"fcntl failed");
292 std::perror(
"fcntl failed");
305 std::perror(
"sigaction failed");
311#if defined(__APPLE__)
315 std::cout <<
"CPU affinity cannot be set on macOS" << std::endl;
322 std::cerr <<
"WARNING: CPU affinity setting not implemented on Windows, continuing..." << std::endl;
341 std::cerr <<
"WARNING: Could not set CPU affinity, continuing..." << std::endl;
343 std::cerr <<
"CPU affinity set to cpu " <<
set_cpu <<
" in process " <<
getpid() << std::endl;
368 }
catch (
const std::exception &
e) {
369 std::cerr <<
"WARNING: something in ProcessManager::terminate threw an exception! Original exception message:\n"
370 <<
e.what() << std::endl;
407 printf(
"chill_wait: no children (got ECHILD error code from wait call), done\n");
409 throw std::runtime_error(std::string(
"chill_wait: error in wait call: ") +
strerror(
errno) +
410 std::string(
", errno ") + std::to_string(
errno));
425 std::unordered_set<pid_t> children;
430 children.insert(
pid);
433 while (!children.empty()) {
479 printf(
"I'm not master, queue or worker, weird! PID %d\n",
getpid());
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t mask
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
R__EXTERN C unsigned int sleep(unsigned int seconds)
static bool getTimingAnalysis()
void initialize_processes(bool cpu_pinning=true)
Fork processes and activate CPU pinning.
std::vector< pid_t > worker_pids_
std::array< int, 2 > mq_fds_
std::vector< std::array< int, 2 > > qw_fds_
std::size_t N_workers() const
void close_channel_fds()
Close all channel ends still owned by this ProcessManager (i.e.
static void handle_sigterm(int signum)
We need this to tell the children to die, because we can't talk to them anymore during JobManager des...
static int sigterm_wake_read_fd_
bool is_initialized() const
int claim_mw_fd(std::size_t worker_ix)
Hand over the master-worker channel end for the current process type.
void close_unused_channel_fds()
Close the channel ends that do not belong to the current process type.
static bool sigterm_received()
int claim_mq_fd()
Hand over the master-queue channel end for the current process type.
void wait_for_sigterm_then_exit()
static int sigterm_wake_write_fd_
std::vector< std::array< int, 2 > > mw_fds_
void identify_processes() const
Print to stdout which type of process we are on and what its PID is (for debugging)
static int sigterm_wake_fd()
Read end of the self-pipe that the SIGTERM handler writes to (or -1 on the master process,...
void terminate() noexcept
Shutdown forked processes if on master and if this process manager is initialized.
ProcessManager(std::size_t N_workers)
void shutdown_processes()
Shutdown forked processes if on master.
static volatile sig_atomic_t sigterm_received_
int claim_qw_fd(std::size_t worker_ix)
Hand over the queue-worker channel end for the current process type.
void create_channel_fds()
Create the socketpairs that connect the processes.
std::size_t worker_id() const
static void setup(pid_t proc, bool set_begin=true)
pid_t fork_and_handle_errors()
The namespace RooFit contains mostly switches that change the behaviour of functions of PDFs (or othe...