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:
Peter Wu 2012-08-15 11:40:53 +02:00
parent 3f089117c7
commit 06167128bf
2 changed files with 42 additions and 1 deletions

View file

@ -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;
}

View file

@ -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);
};
};