mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 18:55:19 +00:00 
			
		
		
		
	Merged revisions 302599 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.6.2 ........ r302599 | tilghman | 2011-01-19 14:13:24 -0600 (Wed, 19 Jan 2011) | 15 lines Kill zombies. When we ast_safe_fork() with a non-zero argument, we're expected to reap our own zombies. On a zero argument, however, the zombies are only reaped when there aren't any non-zero forked children alive. At other times, we accumulate zombies. This code is forward ported from res_agi in 1.4, so that forked children are always reaped, thus preventing an accumulation of zombie processes. (closes issue #18515) Reported by: ernied Patches: 20101221__issue18515.diff.txt uploaded by tilghman (license 14) Tested by: ernied ........ git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.8@302634 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
		
							
								
								
									
										61
									
								
								main/app.c
									
									
									
									
									
								
							
							
						
						
									
										61
									
								
								main/app.c
									
									
									
									
									
								
							| @@ -30,10 +30,15 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") | ||||
| #ifdef HAVE_SYS_STAT_H | ||||
| #include <sys/stat.h> | ||||
| #endif | ||||
| #include <regex.h> | ||||
| #include <sys/file.h> /* added this to allow to compile, sorry! */ | ||||
| #include <signal.h> | ||||
| #include <regex.h>          /* for regcomp(3) */ | ||||
| #include <sys/file.h>       /* for flock(2) */ | ||||
| #include <signal.h>         /* for pthread_sigmask(3) */ | ||||
| #include <stdlib.h>         /* for closefrom(3) */ | ||||
| #include <sys/types.h> | ||||
| #include <sys/wait.h>       /* for waitpid(2) */ | ||||
| #ifndef HAVE_CLOSEFROM | ||||
| #include <dirent.h>         /* for opendir(3)   */ | ||||
| #endif | ||||
| #ifdef HAVE_CAP | ||||
| #include <sys/capability.h> | ||||
| #endif /* HAVE_CAP */ | ||||
| @@ -52,6 +57,41 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") | ||||
|  | ||||
| AST_THREADSTORAGE_PUBLIC(ast_str_thread_global_buf); | ||||
|  | ||||
| static pthread_t shaun_of_the_dead_thread = AST_PTHREADT_NULL; | ||||
|  | ||||
| struct zombie { | ||||
| 	pid_t pid; | ||||
| 	AST_LIST_ENTRY(zombie) list; | ||||
| }; | ||||
|  | ||||
| static AST_LIST_HEAD_STATIC(zombies, zombie); | ||||
|  | ||||
| static void *shaun_of_the_dead(void *data) | ||||
| { | ||||
| 	struct zombie *cur; | ||||
| 	int status; | ||||
| 	for (;;) { | ||||
| 		if (!AST_LIST_EMPTY(&zombies)) { | ||||
| 			/* Don't allow cancellation while we have a lock. */ | ||||
| 			pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); | ||||
| 			AST_LIST_LOCK(&zombies); | ||||
| 			AST_LIST_TRAVERSE_SAFE_BEGIN(&zombies, cur, list) { | ||||
| 				if (waitpid(cur->pid, &status, WNOHANG) != 0) { | ||||
| 					AST_LIST_REMOVE_CURRENT(list); | ||||
| 					ast_free(cur); | ||||
| 				} | ||||
| 			} | ||||
| 			AST_LIST_TRAVERSE_SAFE_END | ||||
| 			AST_LIST_UNLOCK(&zombies); | ||||
| 			pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); | ||||
| 		} | ||||
| 		pthread_testcancel(); | ||||
| 		/* Wait for 60 seconds, without engaging in a busy loop. */ | ||||
| 		ast_poll(NULL, 0, AST_LIST_FIRST(&zombies) ? 5000 : 60000); | ||||
| 	} | ||||
| 	return NULL; | ||||
| } | ||||
|  | ||||
|  | ||||
| #define AST_MAX_FORMATS 10 | ||||
|  | ||||
| @@ -2060,6 +2100,21 @@ int ast_safe_fork(int stop_reaper) | ||||
| 	if (pid != 0) { | ||||
| 		/* Fork failed or parent */ | ||||
| 		pthread_sigmask(SIG_SETMASK, &old_set, NULL); | ||||
| 		if (!stop_reaper && pid > 0) { | ||||
| 			struct zombie *cur = ast_calloc(1, sizeof(*cur)); | ||||
| 			if (cur) { | ||||
| 				cur->pid = pid; | ||||
| 				AST_LIST_LOCK(&zombies); | ||||
| 				AST_LIST_INSERT_TAIL(&zombies, cur, list); | ||||
| 				AST_LIST_UNLOCK(&zombies); | ||||
| 				if (shaun_of_the_dead_thread == AST_PTHREADT_NULL) { | ||||
| 					if (ast_pthread_create_background(&shaun_of_the_dead_thread, NULL, shaun_of_the_dead, NULL)) { | ||||
| 						ast_log(LOG_ERROR, "Shaun of the Dead wants to kill zombies, but can't?!!\n"); | ||||
| 						shaun_of_the_dead_thread = AST_PTHREADT_NULL; | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		return pid; | ||||
| 	} else { | ||||
| 		/* Child */ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user