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>
|
#include <stdio.h>
|
||||||
|
|
||||||
std::map<pid_t, std::string> Util::Procs::plist;
|
std::map<pid_t, std::string> Util::Procs::plist;
|
||||||
|
std::map<pid_t, Util::TerminationNotifier> Util::Procs::exitHandlers;
|
||||||
bool Util::Procs::handler_set = false;
|
bool Util::Procs::handler_set = false;
|
||||||
|
|
||||||
/// Used internally to capture child signals and update plist.
|
/// Used internally to capture child signals and update plist.
|
||||||
void Util::Procs::childsig_handler(int signum){
|
void Util::Procs::childsig_handler(int signum){
|
||||||
if (signum != SIGCHLD){return;}
|
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
|
#if DEBUG >= 1
|
||||||
std::string pname = plist[ret];
|
std::string pname = plist[ret];
|
||||||
#endif
|
#endif
|
||||||
|
@ -34,9 +51,19 @@ void Util::Procs::childsig_handler(int signum){
|
||||||
if (isActive(pname)){
|
if (isActive(pname)){
|
||||||
Stop(pname);
|
Stop(pname);
|
||||||
}else{
|
}else{
|
||||||
|
//can this ever happen?
|
||||||
std::cerr << "Process " << pname << " fully terminated." << std::endl;
|
std::cerr << "Process " << pname << " fully terminated." << std::endl;
|
||||||
}
|
}
|
||||||
#endif
|
#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.
|
/// Attempts to run the command cmd.
|
||||||
|
@ -358,3 +385,13 @@ std::string Util::Procs::getName(pid_t name){
|
||||||
}
|
}
|
||||||
return "";
|
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
|
/// Contains utility code, not directly related to streaming media
|
||||||
namespace Util{
|
namespace Util{
|
||||||
|
|
||||||
|
typedef void (*TerminationNotifier)(pid_t pid, int exitCode);
|
||||||
|
|
||||||
/// Deals with spawning, monitoring and stopping child processes
|
/// Deals with spawning, monitoring and stopping child processes
|
||||||
class Procs{
|
class Procs{
|
||||||
private:
|
private:
|
||||||
static std::map<pid_t, std::string> plist; ///< Holds active processes
|
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 bool handler_set; ///< If true, the sigchld handler has been setup.
|
||||||
static void childsig_handler(int signum);
|
static void childsig_handler(int signum);
|
||||||
static void runCmd(std::string & cmd);
|
static void runCmd(std::string & cmd);
|
||||||
|
@ -28,6 +31,7 @@ namespace Util{
|
||||||
static bool isActive(pid_t name);
|
static bool isActive(pid_t name);
|
||||||
static pid_t getPid(std::string name);
|
static pid_t getPid(std::string name);
|
||||||
static std::string getName(pid_t name);
|
static std::string getName(pid_t name);
|
||||||
|
static bool SetTerminationNotifier(pid_t pid, TerminationNotifier notifier);
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Reference in a new issue