Correct handling of reaper thread in forking binaries
This commit is contained in:
		
							parent
							
								
									ddd9e8c67d
								
							
						
					
					
						commit
						bffd81f27e
					
				
					 5 changed files with 33 additions and 2 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{ | ||||||
|  |  | ||||||
|  | @ -475,10 +475,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; | ||||||
|  | @ -488,6 +488,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; | ||||||
|  |  | ||||||
|  | @ -157,8 +157,10 @@ namespace Mist { | ||||||
|     config->activate(); |     config->activate(); | ||||||
|     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]; | ||||||
|  | @ -173,6 +175,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
		Add a link
		
	
		Reference in a new issue
	
	 Thulinma
						Thulinma