[launchd-changes] [23042] trunk/launchd/src

source_changes at macosforge.org source_changes at macosforge.org
Thu Feb 8 07:21:27 PST 2007


Revision: 23042
          http://trac.macosforge.org/projects/launchd/changeset/23042
Author:   zarzycki at apple.com
Date:     2007-02-08 07:21:26 -0800 (Thu, 08 Feb 2007)

Log Message:
-----------
<rdar://problem/4943031> Add plist option to mimic the kernel's KERN_PROCDELAYTERM

Modified Paths:
--------------
    trunk/launchd/src/launchd.c
    trunk/launchd/src/launchd.h
    trunk/launchd/src/launchd.plist.5
    trunk/launchd/src/launchd_core_logic.c
    trunk/launchd/src/launchd_core_logic.h
    trunk/launchd/src/liblaunch_public.h

Modified: trunk/launchd/src/launchd.c
===================================================================
--- trunk/launchd/src/launchd.c	2007-02-08 01:28:03 UTC (rev 23041)
+++ trunk/launchd/src/launchd.c	2007-02-08 15:21:26 UTC (rev 23042)
@@ -110,7 +110,7 @@
 static const char *launchctl_bootstrap_tool[] = { "/bin/launchctl", /* "bootstrap", */ NULL };
 
 sigset_t blocked_signals = 0;
-bool shutdown_in_progress = false;
+static bool shutdown_in_progress = false;
 bool debug_shutdown_hangs = false;
 bool network_up = false;
 int batch_disabler_count = 0;
@@ -469,7 +469,7 @@
 
 	rlcj = NULL;
 
-	jobmgr_remove_all_inactive(root_jobmgr);
+	root_jobmgr = jobmgr_shutdown(root_jobmgr);
 }
 
 void
@@ -676,7 +676,7 @@
 void
 launchd_post_kevent(void)
 {
-	if (shutdown_in_progress && jobmgr_is_idle(root_jobmgr)) {
+	if (shutdown_in_progress && (!root_jobmgr || jobmgr_is_idle(root_jobmgr))) {
 		shutdown_in_progress = false;
 
 		if (getpid() == 1) {

Modified: trunk/launchd/src/launchd.h
===================================================================
--- trunk/launchd/src/launchd.h	2007-02-08 01:28:03 UTC (rev 23041)
+++ trunk/launchd/src/launchd.h	2007-02-08 15:21:26 UTC (rev 23042)
@@ -34,7 +34,6 @@
 
 extern kq_callback kqsimple_zombie_reaper;
 extern sigset_t blocked_signals;
-extern bool shutdown_in_progress;
 extern bool debug_shutdown_hangs;
 extern bool network_up;
 extern int batch_disabler_count;

Modified: trunk/launchd/src/launchd.plist.5
===================================================================
--- trunk/launchd/src/launchd.plist.5	2007-02-08 01:28:03 UTC (rev 23041)
+++ trunk/launchd/src/launchd.plist.5	2007-02-08 15:21:26 UTC (rev 23042)
@@ -271,6 +271,12 @@
 This optional key specifies what
 .Xr nice 3
 value should be applied to the daemon.
+.It Sy HopefullyExitsLast <boolean>
+This optional key causes programs to exit in a second wave during system
+shutdown. This key exists because some jobs don't reference count their
+clients, and therefore do not know when it is safe to exit. The use of this key
+should be considered a temporary solution until the software can be changed to
+properly reference count clients.
 .It Sy LowPriorityIO <boolean>
 This optional key specifies whether the kernel should consider this daemon to be low priority when doing file system I/O.
 .It Sy LaunchOnlyOnce <boolean>

Modified: trunk/launchd/src/launchd_core_logic.c
===================================================================
--- trunk/launchd/src/launchd_core_logic.c	2007-02-08 01:28:03 UTC (rev 23041)
+++ trunk/launchd/src/launchd_core_logic.c	2007-02-08 15:21:26 UTC (rev 23042)
@@ -199,7 +199,7 @@
 	char *jm_stdout;
 	char *jm_stderr;
 	unsigned int global_on_demand_cnt;
-	unsigned int transfer_bstrap:1;
+	unsigned int transfer_bstrap:1, sent_stop_to_hopeful_jobs:1, shutting_down:1;
 	char name[0];
 };
 
@@ -208,6 +208,7 @@
 
 static jobmgr_t jobmgr_new(jobmgr_t jm, mach_port_t requestorport, mach_port_t checkin_port);
 static jobmgr_t jobmgr_parent(jobmgr_t jm);
+static jobmgr_t jobmgr_tickle(jobmgr_t jm);
 static void jobmgr_dispatch_all(jobmgr_t jm);
 static job_t jobmgr_new_anonymous(jobmgr_t jm);
 static job_t job_mig_intran2(jobmgr_t jm, mach_port_t p);
@@ -268,7 +269,7 @@
 		     anonymous:1;
 	mode_t mask;
 	unsigned int globargv:1, wait4debugger:1, unload_at_exit:1, stall_before_exec:1, only_once:1,
-		     currently_ignored:1, forced_peers_to_demand_mode:1, setnice:1;
+		     currently_ignored:1, forced_peers_to_demand_mode:1, setnice:1, hopefully_exits_last:1;
 	char label[0];
 };
 
@@ -510,23 +511,27 @@
 	return r;
 }
 
-void
-jobmgr_remove_all_inactive(jobmgr_t jm)
+jobmgr_t
+jobmgr_shutdown(jobmgr_t jm)
 {
 	jobmgr_t jmi, jmn;
 	job_t ji, jn;
 
 	SLIST_FOREACH_SAFE(jmi, &jm->submgrs, sle, jmn) {
-		jobmgr_remove_all_inactive(jmi);
+		jobmgr_shutdown(jmi);
 	}
 
 	SLIST_FOREACH_SAFE(ji, &jm->jobs, sle, jn) {
 		if (!job_active(ji)) {
 			job_remove(ji);
-		} else {
+		} else if (!ji->hopefully_exits_last) {
 			job_stop(ji);
 		}
 	}
+
+	jm->shutting_down = true;
+
+	return jobmgr_tickle(jm);
 }
 
 void
@@ -595,10 +600,6 @@
 		}
 	}
 
-	if (job_assumes(j, j->mgr)) {
-		SLIST_REMOVE(&j->mgr->jobs, j, job_s, sle);
-	}
-
 	if (j->forkfd) {
 		job_assumes(j, close(j->forkfd) != -1);
 	}
@@ -672,6 +673,12 @@
 	}
 
 	kevent_mod((uintptr_t)j, EVFILT_TIMER, EV_DELETE, 0, 0, NULL);
+
+	if (job_assumes(j, j->mgr)) {
+		SLIST_REMOVE(&j->mgr->jobs, j, job_s, sle);
+		jobmgr_tickle(j->mgr);
+	}
+
 	free(j);
 }
 
@@ -894,7 +901,7 @@
 	int i, cc = 0;
 	job_t j;
 
-	if (shutdown_in_progress) {
+	if (jm->shutting_down) {
 		errno = EINVAL;
 		return NULL;
 	}
@@ -1036,6 +1043,12 @@
 			j->debug = value;
 		}
 		break;
+	case 'h':
+	case 'H':
+		if (strcasecmp(key, LAUNCH_JOBKEY_HOPEFULLYEXITSLAST) == 0) {
+			j->hopefully_exits_last = value;
+		}
+		break;
 	case 's':
 	case 'S':
 		if (strcasecmp(key, LAUNCH_JOBKEY_SESSIONCREATE) == 0) {
@@ -2805,7 +2818,7 @@
 		}
 		job_log(j, LOG_INFO, "Exited. Was only configured to run once.");
 		return true;
-	} else if (shutdown_in_progress) {
+	} else if (j->mgr->shutting_down) {
 		job_log(j, LOG_INFO, "Exited while shutdown in progress.");
 		return true;
 	} else if (!j->checkedin && (!SLIST_EMPTY(&j->sockets) || !SLIST_EMPTY(&j->machservices))) {
@@ -3162,6 +3175,35 @@
 	}
 }
 
+jobmgr_t
+jobmgr_tickle(jobmgr_t jm)
+{
+	job_t ji;
+
+	if (jm->sent_stop_to_hopeful_jobs || !jm->shutting_down) {
+		return jm;
+	}
+
+	SLIST_FOREACH(ji, &jm->jobs, sle) {
+		if (ji->p && !ji->hopefully_exits_last) {
+			return jm;
+		}
+	}
+
+	SLIST_FOREACH(ji, &jm->jobs, sle) {
+		job_stop(ji);
+	}
+
+	jm->sent_stop_to_hopeful_jobs = true;
+
+	if (jobmgr_is_idle(jm)) {
+		jobmgr_remove(jm);
+		return NULL;
+	}
+
+	return jm;
+}
+
 bool
 jobmgr_is_idle(jobmgr_t jm)
 {
@@ -3321,11 +3363,7 @@
 	 */
 
 	if (jm->req_port == port) {
-		if (jm == root_jobmgr) {
-			launchd_shutdown();
-		} else {
-			return jobmgr_remove(jm);
-		}
+		jobmgr_shutdown(jm);
 	}
 
 	SLIST_FOREACH_SAFE(jmi, &jm->submgrs, sle, jmn) {

Modified: trunk/launchd/src/launchd_core_logic.h
===================================================================
--- trunk/launchd/src/launchd_core_logic.h	2007-02-08 01:28:03 UTC (rev 23041)
+++ trunk/launchd/src/launchd_core_logic.h	2007-02-08 15:21:26 UTC (rev 23042)
@@ -32,7 +32,7 @@
 void jobmgr_set_stdout(jobmgr_t jm, const char *what);
 void jobmgr_set_stderr(jobmgr_t jm, const char *what);
 bool jobmgr_is_idle(jobmgr_t jm);
-void jobmgr_remove_all_inactive(jobmgr_t jm);
+jobmgr_t jobmgr_shutdown(jobmgr_t jm);
 void jobmgr_dispatch_all_semaphores(jobmgr_t jm);
 job_t jobmgr_find(jobmgr_t jm, const char *label);
 void jobmgr_delete_anything_with_port(jobmgr_t jm, mach_port_t port);

Modified: trunk/launchd/src/liblaunch_public.h
===================================================================
--- trunk/launchd/src/liblaunch_public.h	2007-02-08 01:28:03 UTC (rev 23041)
+++ trunk/launchd/src/liblaunch_public.h	2007-02-08 15:21:26 UTC (rev 23042)
@@ -78,6 +78,7 @@
 #define LAUNCH_JOBKEY_USERENVIRONMENTVARIABLES	"UserEnvironmentVariables"
 #define LAUNCH_JOBKEY_UMASK			"Umask"
 #define LAUNCH_JOBKEY_NICE			"Nice"
+#define LAUNCH_JOBKEY_HOPEFULLYEXITSLAST	"HopefullyExitsLast"
 #define LAUNCH_JOBKEY_LOWPRIORITYIO		"LowPriorityIO"
 #define LAUNCH_JOBKEY_SESSIONCREATE		"SessionCreate"
 #define LAUNCH_JOBKEY_SOFTRESOURCELIMITS	"SoftResourceLimits"

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/launchd-changes/attachments/20070208/e8ef388f/attachment.html


More information about the launchd-changes mailing list