Add process termination registration
Edited patch because of context change due to:
commit 28548f35b0
Author: Thulinma <jaron@vietors.com>
Date: Tue Aug 14 20:53:05 2012 +0200
Do not report part-termination of processes.
This commit is contained in:
parent
3f089117c7
commit
06167128bf
2 changed files with 42 additions and 1 deletions
|
@ -20,12 +20,29 @@
|
|||
#include <stdio.h>
|
||||
|
||||
std::map<pid_t, std::string> Util::Procs::plist;
|
||||
std::map<pid_t, Util::TerminationNotifier> Util::Procs::exitHandlers;
|
||||
bool Util::Procs::handler_set = false;
|
||||
|
||||
/// Used internally to capture child signals and update plist.
|
||||
void Util::Procs::childsig_handler(int signum){
|
||||
if (signum != SIGCHLD){return;}
|
||||
pid_t ret = wait(0);
|
||||
int status;
|
||||
pid_t ret = waitpid(-1, &status, WNOHANG);
|
||||
if (ret == 0){//ignore, would block otherwise
|
||||
return;
|
||||
}else if(ret < 0){
|
||||
#if DEBUG >= 3
|
||||
std::cerr << "SIGCHLD received, but no child died";
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
int exitcode;
|
||||
if (WIFEXITED(status)){
|
||||
exitcode = WEXITSTATUS(status);
|
||||
}else if (WIFSIGNALED(status)){
|
||||
exitcode = -WTERMSIG(status);
|
||||
}else{/* not possible */return;}
|
||||
|
||||
#if DEBUG >= 1
|
||||
std::string pname = plist[ret];
|
||||
#endif
|
||||
|
@ -34,9 +51,19 @@ void Util::Procs::childsig_handler(int signum){
|
|||
if (isActive(pname)){
|
||||
Stop(pname);
|
||||
}else{
|
||||
//can this ever happen?
|
||||
std::cerr << "Process " << pname << " fully terminated." << std::endl;
|
||||
}
|
||||
#endif
|
||||
|
||||
TerminationNotifier tn = exitHandlers[ret];
|
||||
exitHandlers.erase(ret);
|
||||
if (tn){
|
||||
#if DEBUG >= 2
|
||||
std::cerr << "Calling termination handler for " << pname << std::endl;
|
||||
#endif
|
||||
tn(ret, exitcode);
|
||||
}
|
||||
}
|
||||
|
||||
/// Attempts to run the command cmd.
|
||||
|
@ -358,3 +385,13 @@ std::string Util::Procs::getName(pid_t name){
|
|||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/// Registers one notifier function for when a process indentified by PID terminates.
|
||||
/// \return true if the notifier could be registered, false otherwise.
|
||||
bool Util::Procs::SetTerminationNotifier(pid_t pid, TerminationNotifier notifier){
|
||||
if (plist.find(pid) != plist.end()){
|
||||
exitHandlers[pid] = notifier;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -9,10 +9,13 @@
|
|||
/// Contains utility code, not directly related to streaming media
|
||||
namespace Util{
|
||||
|
||||
typedef void (*TerminationNotifier)(pid_t pid, int exitCode);
|
||||
|
||||
/// Deals with spawning, monitoring and stopping child processes
|
||||
class Procs{
|
||||
private:
|
||||
static std::map<pid_t, std::string> plist; ///< Holds active processes
|
||||
static std::map<pid_t, TerminationNotifier> exitHandlers; ///< termination function, if any
|
||||
static bool handler_set; ///< If true, the sigchld handler has been setup.
|
||||
static void childsig_handler(int signum);
|
||||
static void runCmd(std::string & cmd);
|
||||
|
@ -28,6 +31,7 @@ namespace Util{
|
|||
static bool isActive(pid_t name);
|
||||
static pid_t getPid(std::string name);
|
||||
static std::string getName(pid_t name);
|
||||
static bool SetTerminationNotifier(pid_t pid, TerminationNotifier notifier);
|
||||
};
|
||||
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue