6 #include <framework/pcore/ProcHandler.h>
7 #include <framework/core/InputController.h>
8 #include <framework/logging/Logger.h>
9 #include <framework/core/EventProcessor.h>
10 #include <framework/pcore/GlobalProcHandler.h>
15 #include <sys/prctl.h>
27 static int s_processID = -1;
28 static int s_numEventProcesses = 0;
29 static int s_localChildrenWithErrors = 0;
35 static std::vector<int> s_pidVector;
36 static int* s_pids =
nullptr;
37 static int s_numpids = 0;
41 bool found_gap =
false;
42 for (
int i = 0; i < s_numpids; i++) {
51 if (s_pidVector.size() == s_pidVector.capacity()) {
52 B2FATAL(
"PID vector at capacity. This produces a race condition, make sure ProcHandler is created early.");
54 s_pidVector.push_back(pid);
56 s_pids = s_pidVector.data();
57 s_numpids = s_pidVector.size();
64 for (
int i = 0; i < s_numpids; i++)
65 if (std::abs(s_pids[i]) == std::abs(pid))
69 void removePID(
int pid)
71 for (
int i = 0; i < s_numpids; i++)
72 if (std::abs(s_pids[i]) == std::abs(pid))
77 for (
int i = 0; i < s_numpids; i++)
82 for (
int i = 0; i < s_numpids; i++)
88 void sigChldHandler(
int)
92 while (!pidListEmpty()) {
94 int pid = waitpid(-1, &status, WNOHANG);
98 }
else if (errno == ECHILD) {
100 EventProcessor::writeToStdErr(
"\n Called waitpid() without any children left. This shouldn't happen and and indicates a problem.\n");
108 EventProcessor::writeToStdErr(
"\nwaitpid() failed.\n");
110 }
else if (pid == 0) {
121 if (WIFSIGNALED(status)) {
124 termSig = WTERMSIG(status);
127 if (termSig == SIGSEGV)
129 }
else if (WIFEXITED(status) and WEXITSTATUS(status) != 0) {
130 EventProcessor::writeToStdErr(
"\nExecution stopped, sub-process exited with non-zero exit status. Please check other log messages for details.\n");
136 s_localChildrenWithErrors++;
151 bool ProcHandler::startProc(std::set<int>* processList,
const std::string& procType,
int id)
153 EventProcessor::installSignalHandler(SIGCHLD, sigChldHandler);
159 if (m_markChildrenAsLocal)
161 processList->insert(pid);
163 B2INFO(
"ProcHandler: " << procType <<
" process forked. pid = " << pid);
165 }
else if (pid < 0) {
166 B2FATAL(
"fork() failed: " << strerror(errno));
169 EventProcessor::installSignalHandler(SIGCHLD, SIG_IGN);
175 InputController::resetForChildProcess();
177 prctl(PR_SET_PDEATHSIG, SIGHUP);
183 ProcHandler::ProcHandler(
unsigned int nWorkerProc,
bool markChildrenAsLocal):
184 m_markChildrenAsLocal(markChildrenAsLocal),
185 m_numWorkerProcesses(nWorkerProc)
187 if ((
int)nWorkerProc > s_numEventProcesses)
188 s_numEventProcesses = nWorkerProc;
191 B2FATAL(
"Constructing ProcHandler after forking is not allowed!");
194 s_pidVector.reserve(s_pidVector.size() + nWorkerProc + 2);
195 s_pids = s_pidVector.data();
217 if (s_processID == -1)
231 return s_numEventProcesses;
236 return std::set<int>(s_pidVector.begin(), s_pidVector.end());
267 if (findPID(pid) == 0) {
271 s_localChildrenWithErrors--;