Skip to content

Commit 8662a04

Browse files
jackal1-66sawenzel
authored andcommitted
Fix for subjob spawning with FIFOs
1 parent c4c7026 commit 8662a04

File tree

3 files changed

+69
-6
lines changed

3 files changed

+69
-6
lines changed

Generators/include/Generators/GeneratorFileOrCmd.h

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,12 @@ struct GeneratorFileOrCmd {
4646
* execute, but should not include pipes.
4747
*/
4848
void setCmd(const std::string& cmd) { mCmd = cmd; }
49+
/**
50+
* Set command child process PID
51+
*
52+
* @param cmdPid child process PID.
53+
*/
54+
void setCmdPid(const pid_t cmdPid) { mCmdPid = cmdPid; }
4955
/**
5056
* Set the number of events that a background command should
5157
* generate. This should come from @c SimConfig::getNEents.
@@ -132,7 +138,14 @@ struct GeneratorFileOrCmd {
132138
* @return true if the background command line was executed, false
133139
* otherwise.
134140
*/
135-
virtual bool executeCmdLine(const std::string& cmd) const;
141+
virtual bool executeCmdLine(const std::string& cmd);
142+
/**
143+
* Terminates the background command using PID of the child
144+
* process generated by fork.
145+
*
146+
* @return true if the process was terminated successfully
147+
*/
148+
virtual bool terminateCmd();
136149
/**
137150
* Create a temporary file (and close it immediately). On success,
138151
* the list of file names is cleared and the name of the temporary
@@ -236,6 +249,10 @@ struct GeneratorFileOrCmd {
236249
* Time in miliseconds between each wait for data
237250
*/
238251
int mWait = 500;
252+
/**
253+
* PID of the background command
254+
*/
255+
int mCmdPid = -1;
239256
};
240257

241258
} // namespace eventgen

Generators/src/GeneratorFileOrCmd.cxx

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616
// For fifo's and system call
1717
#include <cstdlib>
1818
#include <sys/types.h> // POSIX only
19-
#include <sys/stat.h> // POISX only
19+
#include <sys/stat.h> // POSIX only
20+
#include <csignal>
21+
#include <sys/wait.h>
2022
#include <cstdio>
2123
// For filesystem operations
2224
#include <filesystem>
@@ -115,14 +117,52 @@ std::string GeneratorFileOrCmd::makeCmdLine() const
115117
return s.str();
116118
}
117119
// -----------------------------------------------------------------
118-
bool GeneratorFileOrCmd::executeCmdLine(const std::string& cmd) const
120+
bool GeneratorFileOrCmd::executeCmdLine(const std::string& cmd)
119121
{
120122
LOG(info) << "Command line to execute: \"" << cmd << "\"";
121-
int ret = std::system(cmd.c_str());
122-
if (ret != 0) {
123-
LOG(fatal) << "Failed to spawn \"" << cmd << "\"";
123+
// Fork a new process
124+
pid_t pid = fork();
125+
if (pid == -1) {
126+
LOG(fatal) << "Failed to fork process: " << std::strerror(errno);
124127
return false;
125128
}
129+
130+
if (pid == 0) {
131+
// Child process
132+
setsid();
133+
execl("/bin/sh", "sh", "-c", cmd.c_str(), (char*)nullptr);
134+
// If execl returns, there was an error, otherwise following lines will not be executed
135+
LOG(fatal) << "Failed to execute command: " << std::strerror(errno);
136+
_exit(EXIT_FAILURE);
137+
} else {
138+
// Parent process
139+
setCmdPid(pid);
140+
LOG(info) << "Child spawned process group is running with PID: " << mCmdPid;
141+
}
142+
return true;
143+
}
144+
// -----------------------------------------------------------------
145+
bool GeneratorFileOrCmd::terminateCmd()
146+
{
147+
if (mCmdPid == -1) {
148+
LOG(info) << "No command is currently running";
149+
return false;
150+
}
151+
152+
LOG(info) << "Terminating process ID group " << mCmdPid;
153+
if (kill(-mCmdPid, SIGKILL) == -1) {
154+
LOG(fatal) << "Failed to kill process: " << std::strerror(errno);
155+
return false;
156+
}
157+
158+
// Wait for the process to terminate
159+
int status;
160+
if (waitpid(mCmdPid, &status, 0) == -1) {
161+
LOG(fatal) << "Failed to wait for process termination: " << std::strerror(errno);
162+
return false;
163+
}
164+
165+
mCmdPid = -1; // Reset the process ID
126166
return true;
127167
}
128168
// -----------------------------------------------------------------

Generators/src/GeneratorHepMC.cxx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,12 @@ GeneratorHepMC::~GeneratorHepMC()
6565
if (mEvent) {
6666
delete mEvent;
6767
}
68+
if (not mCmd.empty()) {
69+
// Must be executed before removing the temporary file
70+
// otherwise the current child process might still be writing on it
71+
// causing unwanted stdout messages which could slow down the system
72+
terminateCmd();
73+
}
6874
removeTemp();
6975
}
7076

0 commit comments

Comments
 (0)