[launchd-changes] [23812] branches/PR-6562592/launchd/src/launchd_core_logic.c

source_changes at macosforge.org source_changes at macosforge.org
Tue Feb 17 02:11:43 PST 2009


Revision: 23812
          http://trac.macosforge.org/projects/launchd/changeset/23812
Author:   dsorresso at apple.com
Date:     2009-02-17 02:11:41 -0800 (Tue, 17 Feb 2009)
Log Message:
-----------
Capped the time we'll wait for all the stray processes at shutdown to exit at three seconds flat, so it won't grow linearly with the number of strays anymore.

Modified Paths:
--------------
    branches/PR-6562592/launchd/src/launchd_core_logic.c

Modified: branches/PR-6562592/launchd/src/launchd_core_logic.c
===================================================================
--- branches/PR-6562592/launchd/src/launchd_core_logic.c	2009-02-17 07:53:40 UTC (rev 23811)
+++ branches/PR-6562592/launchd/src/launchd_core_logic.c	2009-02-17 10:11:41 UTC (rev 23812)
@@ -371,7 +371,7 @@
 static bool jobmgr_label_test(jobmgr_t jm, const char *str);
 static void jobmgr_reap_bulk(jobmgr_t jm, struct kevent *kev);
 static void jobmgr_log_stray_children(jobmgr_t jm, bool kill_strays);
-static void jobmgr_kill_stray_child(jobmgr_t jm, pid_t p);
+static void jobmgr_kill_stray_child(jobmgr_t jm, pid_t *p, size_t np);
 static void jobmgr_remove(jobmgr_t jm);
 static void jobmgr_dispatch_all(jobmgr_t jm, bool newmounthack);
 static void jobmgr_dequeue_next_sample(jobmgr_t jm);
@@ -5585,7 +5585,7 @@
 }
 
 void
-jobmgr_kill_stray_child(jobmgr_t jm, pid_t p)
+jobmgr_kill_stray_child(jobmgr_t jm, pid_t *p, size_t np)
 {
 	struct timespec tts = { 2, 0 }; /* Wait 2 seconds for stray children to die after being SIGTERM'ed. */
 	struct timespec kts = { 1, 0 }; /* Wait 1 second for stray children to die after being SIGKILL'ed. */
@@ -5597,39 +5597,64 @@
 		return;
 	}
 
-	EV_SET(&kev, p, EVFILT_PROC, EV_ADD, 0, 0, 0);
-
-	if (!jobmgr_assumes(jm, kevent(kq, &kev, 1, NULL, 0, NULL) != -1)) {
-		goto out;
-	}
-
 	start = runtime_get_opaque_time();
-
-	if (!jobmgr_assumes(jm, runtime_kill(p, SIGTERM) != -1)) {
-		goto out;
+	size_t i = 0, ns = 0;
+	for( i = 0; i < np; i++ ) {
+		if( p[i] != 0 ) {
+			EV_SET(&kev, p[i], EVFILT_PROC, EV_ADD, NOTE_EXIT, 0, 0);
+			
+			if( jobmgr_assumes(jm, kevent(kq, &kev, 1, NULL, 0, NULL) != -1) ) {
+				ns++;
+			}
+			jobmgr_assumes(jm, runtime_kill(p[i], SIGTERM) != -1);
+		}
 	}
 
-	r = kevent(kq, NULL, 0, &kev, 1, &tts);
-
-	if (!jobmgr_assumes(jm, r == 0 || r == 1)) {
-		goto out;
+	size_t nd = 0;
+	while( (r = kevent(kq, NULL, 0, &kev, 1, &tts)) ) {
+		int status = 0;
+		waitpid((pid_t)kev.ident, &status, WNOHANG);
+		nd++;
+		
+		end = runtime_get_opaque_time();
+		nanosec = runtime_opaque_time_to_nano(end - start);
+		jobmgr_log(jm, LOG_DEBUG | LOG_CONSOLE, "PID %u died after %llu nanoseconds.", (pid_t)kev.ident, nanosec);
+		
+		for( i = 0; i < np; i++ ) {
+			p[i] = ( p[i] == (pid_t)kev.ident ) ? 0 : p[i];
+		}
 	}
 
-	if (r == 0 && jobmgr_assumes(jm, runtime_kill(p, SIGKILL) != -1)) {
-		jobmgr_assumes(jm, (r = kevent(kq, NULL, 0, &kev, 1, &kts)) == 1);
+	for( i = 0; i < np; i++ ) {
+		if( p[i] != 0 ) {
+			EV_SET(&kev, p[i], EVFILT_PROC, EV_ADD, NOTE_EXIT, 0, 0);
+			
+			if( jobmgr_assumes(jm, kevent(kq, &kev, 1, NULL, 0, NULL) != -1) ) {
+				ns++;
+			}
+			jobmgr_assumes(jm, runtime_kill(p[i], SIGKILL) != -1);
+		}
 	}
 
-	end = runtime_get_opaque_time();
-
-	nanosec = runtime_opaque_time_to_nano(end - start);
-
-	jobmgr_log(jm, LOG_DEBUG | LOG_CONSOLE, "PID %u %s after %llu nanoseconds", p, r == 0 ? "did not die" : "died", nanosec);
-	if( r == 0 ) {
-		jobmgr_log(jm, LOG_DEBUG | LOG_CONSOLE, "Disregarding PID %u and continuing.", p);
+	while( (r = kevent(kq, NULL, 0, &kev, 1, &kts)) ) {
+		int status = 0;
+		waitpid((pid_t)kev.ident, &status, WNOHANG);
+		nd++;
+		
+		end = runtime_get_opaque_time();
+		nanosec = runtime_opaque_time_to_nano(end - start);
+		jobmgr_log(jm, LOG_DEBUG | LOG_CONSOLE, "PID %u was killed and died after %llu nanoseconds.", (pid_t)kev.ident, nanosec);
+		
+		for( i = 0; i < np; i++ ) {
+			p[i] = ( p[i] == (pid_t)kev.ident ) ? 0 : p[i];
+		}
 	}
 	
-out:
-	jobmgr_assumes(jm, runtime_close(kq) != -1);
+	for( i = 0; i < np; i++ ) {
+		if( p[i] != 0 ) {
+			jobmgr_log(jm, LOG_DEBUG | LOG_CONSOLE, "Disregarding PID %u and continuing.", p[i]);
+		}
+	}
 }
 
 void
@@ -5654,7 +5679,8 @@
 	}
 
 	kp_cnt = len / sizeof(struct kinfo_proc);
-
+	pid_t *ps = (pid_t *)calloc(sizeof(pid_t), kp_cnt);
+	
 	for (i = 0; i < kp_cnt; i++) {
 		pid_t p_i = kp[i].kp_proc.p_pid;
 		pid_t pp_i = kp[i].kp_eproc.e_ppid;
@@ -5672,17 +5698,21 @@
 		if( !j || (j && j->anonymous) ) {
 			jobmgr_log(jm, LOG_WARNING | LOG_CONSOLE, "Stray %s %s at shutdown: PID %u PPID %u PGID %u %s", z, j ? "anonymous job" : "process", p_i, pp_i, pg_i, n);
 			
-			if( kill_strays ) {
-				jobmgr_kill_stray_child(jm, p_i);
+			int status = 0;
+			if( (kp[i].kp_proc.p_stat == SZOMB) && waitpid(p_i, &status, WNOHANG) == 0 ) {
+				jobmgr_log(jm, LOG_NOTICE | LOG_CONSOLE, "Unreaped zombie stray exited with status %i.", WEXITSTATUS(status));
+			} else {
+				ps[i] = p_i;
 			}
 		}
 	}
 
-out:
-	if (kp_cnt == kp_skipped) {
-		jobmgr_log(jm, LOG_DEBUG, "No stray processes at shutdown");
+	if( (kp_cnt - kp_skipped > 0) && kill_strays ) {
+		jobmgr_kill_stray_child(jm, ps, kp_cnt - kp_skipped);
 	}
 
+	free(ps);
+out:
 	free(kp);
 }
 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/launchd-changes/attachments/20090217/4dff9611/attachment-0001.html>


More information about the launchd-changes mailing list