Correct handling of reaper thread in forking binaries
This commit is contained in:
parent
5f8518fe23
commit
dbafdf6744
5 changed files with 36 additions and 7 deletions
|
@ -157,6 +157,28 @@ void Util::Procs::exit_handler() {
|
||||||
FAIL_MSG("Giving up with %d children left.", (int)listcopy.size());
|
FAIL_MSG("Giving up with %d children left.", (int)listcopy.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Joins the reaper thread, if any, before a fork
|
||||||
|
void Util::Procs::fork_prepare(){
|
||||||
|
tthread::lock_guard<tthread::mutex> guard(plistMutex);
|
||||||
|
if (handler_set){
|
||||||
|
thread_handler = false;
|
||||||
|
if (reaper_thread){
|
||||||
|
reaper_thread->join();
|
||||||
|
delete reaper_thread;
|
||||||
|
reaper_thread = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Restarts reaper thread if it was joined
|
||||||
|
void Util::Procs::fork_complete(){
|
||||||
|
tthread::lock_guard<tthread::mutex> guard(plistMutex);
|
||||||
|
if (handler_set){
|
||||||
|
thread_handler = true;
|
||||||
|
reaper_thread = new tthread::thread(grim_reaper, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Sets up exit and childsig handlers.
|
/// Sets up exit and childsig handlers.
|
||||||
/// Spawns grim_reaper. exit handler despawns grim_reaper
|
/// Spawns grim_reaper. exit handler despawns grim_reaper
|
||||||
/// Called by every Start* function.
|
/// Called by every Start* function.
|
||||||
|
|
|
@ -26,6 +26,8 @@ namespace Util {
|
||||||
static bool childRunning(pid_t p);
|
static bool childRunning(pid_t p);
|
||||||
static tthread::thread * reaper_thread;
|
static tthread::thread * reaper_thread;
|
||||||
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 fork_prepare();
|
||||||
|
static void fork_complete();
|
||||||
static void setHandler();
|
static void setHandler();
|
||||||
static std::string getOutputOf(char * const * argv);
|
static std::string getOutputOf(char * const * argv);
|
||||||
static std::string getOutputOf(std::deque<std::string> & argDeq);
|
static std::string getOutputOf(std::deque<std::string> & argDeq);
|
||||||
|
|
|
@ -245,8 +245,10 @@ namespace Util{
|
||||||
int pipeErr[2];
|
int pipeErr[2];
|
||||||
if (pipe(pipeErr) >= 0){
|
if (pipe(pipeErr) >= 0){
|
||||||
//Start reading log messages from the unnamed pipe
|
//Start reading log messages from the unnamed pipe
|
||||||
|
Util::Procs::fork_prepare();
|
||||||
pid_t pid = fork();
|
pid_t pid = fork();
|
||||||
if (pid == 0) { //child
|
if (pid == 0) { //child
|
||||||
|
Util::Procs::fork_complete();
|
||||||
close(pipeErr[1]); // close the unneeded pipe file descriptor
|
close(pipeErr[1]); // close the unneeded pipe file descriptor
|
||||||
//Close all sockets in the socketList
|
//Close all sockets in the socketList
|
||||||
for (std::set<int>::iterator it = Util::Procs::socketList.begin(); it != Util::Procs::socketList.end(); ++it){
|
for (std::set<int>::iterator it = Util::Procs::socketList.begin(); it != Util::Procs::socketList.end(); ++it){
|
||||||
|
@ -264,6 +266,7 @@ namespace Util{
|
||||||
Util::logParser(pipeErr[0], true_stderr, isatty(true_stderr));
|
Util::logParser(pipeErr[0], true_stderr, isatty(true_stderr));
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
Util::Procs::fork_complete();
|
||||||
if (pid == -1){
|
if (pid == -1){
|
||||||
FAIL_MSG("Failed to fork child process for log handling!");
|
FAIL_MSG("Failed to fork child process for log handling!");
|
||||||
}else{
|
}else{
|
||||||
|
|
|
@ -596,10 +596,10 @@ int main(int argc, char **argv){
|
||||||
Controller::conf.activate();
|
Controller::conf.activate();
|
||||||
uint64_t reTimer = 0;
|
uint64_t reTimer = 0;
|
||||||
while (Controller::conf.is_active){
|
while (Controller::conf.is_active){
|
||||||
|
Util::Procs::fork_prepare();
|
||||||
pid_t pid = fork();
|
pid_t pid = fork();
|
||||||
if (pid == 0){
|
if (pid == 0){
|
||||||
Util::Procs::handler_set = false;
|
Util::Procs::fork_complete();
|
||||||
Util::Procs::reaper_thread = 0;
|
|
||||||
{
|
{
|
||||||
struct sigaction new_action;
|
struct sigaction new_action;
|
||||||
new_action.sa_sigaction = handleUSR1;
|
new_action.sa_sigaction = handleUSR1;
|
||||||
|
@ -609,6 +609,7 @@ int main(int argc, char **argv){
|
||||||
}
|
}
|
||||||
return main_loop(argc, argv);
|
return main_loop(argc, argv);
|
||||||
}
|
}
|
||||||
|
Util::Procs::fork_complete();
|
||||||
if (pid == -1){
|
if (pid == -1){
|
||||||
FAIL_MSG("Unable to spawn controller process!");
|
FAIL_MSG("Unable to spawn controller process!");
|
||||||
return 2;
|
return 2;
|
||||||
|
|
|
@ -310,11 +310,8 @@ namespace Mist {
|
||||||
streamStatus.master = false;
|
streamStatus.master = false;
|
||||||
if (streamStatus){streamStatus.mapped[0] = STRMSTAT_INIT;}
|
if (streamStatus){streamStatus.mapped[0] = STRMSTAT_INIT;}
|
||||||
}
|
}
|
||||||
//Abandon all semaphores, ye who enter here.
|
int ret = 0;
|
||||||
playerLock.abandon();
|
if (preRun()){ret = run();}
|
||||||
pullLock.abandon();
|
|
||||||
if (!preRun()){return 0;}
|
|
||||||
int ret = run();
|
|
||||||
if (playerLock){
|
if (playerLock){
|
||||||
playerLock.unlink();
|
playerLock.unlink();
|
||||||
char pageName[NAME_BUFFER_SIZE];
|
char pageName[NAME_BUFFER_SIZE];
|
||||||
|
@ -322,14 +319,17 @@ namespace Mist {
|
||||||
streamStatus.init(pageName, 1, true, false);
|
streamStatus.init(pageName, 1, true, false);
|
||||||
streamStatus.close();
|
streamStatus.close();
|
||||||
}
|
}
|
||||||
|
playerLock.unlink();
|
||||||
pullLock.unlink();
|
pullLock.unlink();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t reTimer = 0;
|
uint64_t reTimer = 0;
|
||||||
while (config->is_active){
|
while (config->is_active){
|
||||||
|
Util::Procs::fork_prepare();
|
||||||
pid_t pid = fork();
|
pid_t pid = fork();
|
||||||
if (pid == 0){
|
if (pid == 0){
|
||||||
|
Util::Procs::fork_complete();
|
||||||
if (playerLock){
|
if (playerLock){
|
||||||
//Re-init streamStatus, previously closed
|
//Re-init streamStatus, previously closed
|
||||||
char pageName[NAME_BUFFER_SIZE];
|
char pageName[NAME_BUFFER_SIZE];
|
||||||
|
@ -344,6 +344,7 @@ namespace Mist {
|
||||||
if (!preRun()){return 0;}
|
if (!preRun()){return 0;}
|
||||||
return run();
|
return run();
|
||||||
}
|
}
|
||||||
|
Util::Procs::fork_complete();
|
||||||
if (pid == -1){
|
if (pid == -1){
|
||||||
FAIL_MSG("Unable to spawn input process");
|
FAIL_MSG("Unable to spawn input process");
|
||||||
//We failed. Release the kra... semaphores!
|
//We failed. Release the kra... semaphores!
|
||||||
|
|
Loading…
Add table
Reference in a new issue