9 #include <framework/pcore/GlobalProcHandler.h>
10 #include <framework/core/InputController.h>
11 #include <framework/logging/Logger.h>
12 #include <framework/core/EventProcessor.h>
14 #include <framework/pcore/ProcHandler.h>
17 #include <sys/prctl.h>
33 ProcType GlobalProcHandler::s_procType = ProcType::c_Init;
34 int GlobalProcHandler::s_processID = -1;
35 int GlobalProcHandler::s_numEventProcesses = 0;
37 std::vector<int> GlobalProcHandler::s_pidVector;
38 std::map<int, ProcType> GlobalProcHandler::s_startedPIDs;
40 void GlobalProcHandler::childSignalHandler(
int)
42 while (!GlobalProcHandler::pidListEmpty()) {
44 int pid = waitpid(-1, &status, WNOHANG);
48 }
else if (errno == ECHILD) {
50 EventProcessor::writeToStdErr(
"\n Called waitpid() without any children left. This shouldn't happen and and indicates a problem.\n");
53 GlobalProcHandler::clearPIDs();
57 EventProcessor::writeToStdErr(
"\nwaitpid() failed.\n");
59 }
else if (pid == 0) {
66 if (not GlobalProcHandler::findPID(pid)) {
72 if (WIFSIGNALED(status) or (WIFEXITED(status) and WEXITSTATUS(status) != 0)) {
73 EventProcessor::writeToStdErr(
"\nSub-process exited with non-zero exit status. Please check other log messages for details.\n");
77 GlobalProcHandler::removePID(pid);
83 void GlobalProcHandler::addPID(
int newPID)
86 for (
int& pid : s_pidVector) {
93 B2FATAL(
"PID vector at capacity. This produces a race condition, make sure GlobalProcHandler is created early.");
96 bool GlobalProcHandler::findPID(
int pid)
98 return std::find(s_pidVector.begin(), s_pidVector.end(), pid) != s_pidVector.end();
101 void GlobalProcHandler::removePID(
int oldPID)
103 for (
int& pid : s_pidVector) {
111 void GlobalProcHandler::clearPIDs()
113 std::fill(s_pidVector.begin(), s_pidVector.end(), 0);
116 bool GlobalProcHandler::pidListEmpty()
118 for (
const int& pid : s_pidVector) {
126 void GlobalProcHandler::initialize(
unsigned int nWorkerProc)
128 B2ASSERT(
"Constructing GlobalProcHandler after forking is not allowed!", pidListEmpty());
130 s_numEventProcesses = nWorkerProc;
133 s_pidVector.resize(s_pidVector.size() + nWorkerProc + 3, 0);
136 bool GlobalProcHandler::startProxyProcess()
138 return startProc(ProcType::c_Proxy, 30000);
141 bool GlobalProcHandler::startInputProcess()
143 return startProc(ProcType::c_Input, 10000);
146 bool GlobalProcHandler::startWorkerProcesses(
unsigned int numProcesses)
148 for (
unsigned int i = 0; i < numProcesses; i++) {
149 if (startProc(ProcType::c_Worker, 0)) {
156 bool GlobalProcHandler::startOutputProcess(
bool local)
159 s_procType = ProcType::c_Output;
162 return (startProc(ProcType::c_Output, 20000));
166 bool GlobalProcHandler::startMonitoringProcess()
168 s_procType = ProcType::c_Monitor;
172 bool GlobalProcHandler::parallelProcessingUsed()
174 return s_processID != -1;
177 bool GlobalProcHandler::isProcess(
ProcType procType)
179 return (procType == s_procType);
182 bool GlobalProcHandler::startProc(
ProcType procType,
int id)
184 EventProcessor::installSignalHandler(SIGCHLD, childSignalHandler);
192 s_startedPIDs[pid] = procType;
194 }
else if (pid < 0) {
195 B2FATAL(
"fork() failed: " << strerror(errno));
199 EventProcessor::installSignalHandler(SIGCHLD, SIG_IGN);
201 s_procType = procType;
204 s_processID = getpid();
208 ProcHandler::setProcessID(s_processID);
211 PyOS_AfterFork_Child();
213 InputController::resetForChildProcess();
215 prctl(PR_SET_PDEATHSIG, SIGHUP);
221 std::string GlobalProcHandler::getProcessName()
223 if (isProcess(ProcType::c_Worker))
225 if (isProcess(ProcType::c_Input))
227 if (isProcess(ProcType::c_Output))
229 if (isProcess(ProcType::c_Init))
231 if (isProcess(ProcType::c_Monitor))
238 int GlobalProcHandler::EvtProcID()
243 void GlobalProcHandler::killAllProcesses()
245 for (
int& pid : s_pidVector) {
247 if (kill(pid, SIGKILL) >= 0) {
248 B2DEBUG(100,
"hard killed process " << pid);
250 B2DEBUG(100,
"no process " << pid <<
" found, already gone?");
257 const std::vector<int>& GlobalProcHandler::getPIDList()
264 const auto procTypeIt = s_startedPIDs.find(pid);
265 if (procTypeIt == s_startedPIDs.end()) {
266 B2FATAL(
"Asking for a non-existing PID");
268 return procTypeIt->second;
271 int GlobalProcHandler::numEventProcesses()
273 return s_numEventProcesses;
276 bool GlobalProcHandler::isOutputProcess()
278 return isProcess(ProcType::c_Output);
281 bool GlobalProcHandler::isWorkerProcess()
283 return isProcess(ProcType::c_Worker);
286 bool GlobalProcHandler::isInputProcess()
288 return isProcess(ProcType::c_Input);
291 void GlobalProcHandler::waitForAllProcesses()
294 if (pidListEmpty()) {
298 std::this_thread::sleep_for(std::chrono::milliseconds(1));
ProcType
Type of the process used for storing and mapping the child processes in the process handler.
Abstract base class for different kinds of events.