Skip to content

Commit

Permalink
Fix for subjob spawning with FIFOs
Browse files Browse the repository at this point in the history
  • Loading branch information
jackal1-66 authored and sawenzel committed Dec 20, 2024
1 parent c4c7026 commit 8662a04
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 6 deletions.
19 changes: 18 additions & 1 deletion Generators/include/Generators/GeneratorFileOrCmd.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ struct GeneratorFileOrCmd {
* execute, but should not include pipes.
*/
void setCmd(const std::string& cmd) { mCmd = cmd; }
/**
* Set command child process PID
*
* @param cmdPid child process PID.
*/
void setCmdPid(const pid_t cmdPid) { mCmdPid = cmdPid; }
/**
* Set the number of events that a background command should
* generate. This should come from @c SimConfig::getNEents.
Expand Down Expand Up @@ -132,7 +138,14 @@ struct GeneratorFileOrCmd {
* @return true if the background command line was executed, false
* otherwise.
*/
virtual bool executeCmdLine(const std::string& cmd) const;
virtual bool executeCmdLine(const std::string& cmd);
/**
* Terminates the background command using PID of the child
* process generated by fork.
*
* @return true if the process was terminated successfully
*/
virtual bool terminateCmd();
/**
* Create a temporary file (and close it immediately). On success,
* the list of file names is cleared and the name of the temporary
Expand Down Expand Up @@ -236,6 +249,10 @@ struct GeneratorFileOrCmd {
* Time in miliseconds between each wait for data
*/
int mWait = 500;
/**
* PID of the background command
*/
int mCmdPid = -1;
};

} // namespace eventgen
Expand Down
50 changes: 45 additions & 5 deletions Generators/src/GeneratorFileOrCmd.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@
// For fifo's and system call
#include <cstdlib>
#include <sys/types.h> // POSIX only
#include <sys/stat.h> // POISX only
#include <sys/stat.h> // POSIX only
#include <csignal>
#include <sys/wait.h>
#include <cstdio>
// For filesystem operations
#include <filesystem>
Expand Down Expand Up @@ -115,14 +117,52 @@ std::string GeneratorFileOrCmd::makeCmdLine() const
return s.str();
}
// -----------------------------------------------------------------
bool GeneratorFileOrCmd::executeCmdLine(const std::string& cmd) const
bool GeneratorFileOrCmd::executeCmdLine(const std::string& cmd)
{
LOG(info) << "Command line to execute: \"" << cmd << "\"";
int ret = std::system(cmd.c_str());
if (ret != 0) {
LOG(fatal) << "Failed to spawn \"" << cmd << "\"";
// Fork a new process
pid_t pid = fork();
if (pid == -1) {
LOG(fatal) << "Failed to fork process: " << std::strerror(errno);
return false;
}

if (pid == 0) {
// Child process
setsid();
execl("/bin/sh", "sh", "-c", cmd.c_str(), (char*)nullptr);
// If execl returns, there was an error, otherwise following lines will not be executed
LOG(fatal) << "Failed to execute command: " << std::strerror(errno);
_exit(EXIT_FAILURE);
} else {
// Parent process
setCmdPid(pid);
LOG(info) << "Child spawned process group is running with PID: " << mCmdPid;
}
return true;
}
// -----------------------------------------------------------------
bool GeneratorFileOrCmd::terminateCmd()
{
if (mCmdPid == -1) {
LOG(info) << "No command is currently running";
return false;
}

LOG(info) << "Terminating process ID group " << mCmdPid;
if (kill(-mCmdPid, SIGKILL) == -1) {
LOG(fatal) << "Failed to kill process: " << std::strerror(errno);
return false;
}

// Wait for the process to terminate
int status;
if (waitpid(mCmdPid, &status, 0) == -1) {
LOG(fatal) << "Failed to wait for process termination: " << std::strerror(errno);
return false;
}

mCmdPid = -1; // Reset the process ID
return true;
}
// -----------------------------------------------------------------
Expand Down
6 changes: 6 additions & 0 deletions Generators/src/GeneratorHepMC.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,12 @@ GeneratorHepMC::~GeneratorHepMC()
if (mEvent) {
delete mEvent;
}
if (not mCmd.empty()) {
// Must be executed before removing the temporary file
// otherwise the current child process might still be writing on it
// causing unwanted stdout messages which could slow down the system
terminateCmd();
}
removeTemp();
}

Expand Down

0 comments on commit 8662a04

Please sign in to comment.