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

source_changes at macosforge.org source_changes at macosforge.org
Wed Mar 21 11:35:07 PDT 2007


Revision: 23164
          http://trac.macosforge.org/projects/launchd/changeset/23164
Author:   zarzycki at apple.com
Date:     2007-03-21 11:35:06 -0700 (Wed, 21 Mar 2007)

Log Message:
-----------
Hashing is good for the soul.

Modified Paths:
--------------
    trunk/launchd/src/launchd_core_logic.c
    trunk/launchd/src/launchd_core_logic.h
    trunk/launchd/src/launchd_unix_ipc.c

Modified: trunk/launchd/src/launchd_core_logic.c
===================================================================
--- trunk/launchd/src/launchd_core_logic.c	2007-03-21 00:54:01 UTC (rev 23163)
+++ trunk/launchd/src/launchd_core_logic.c	2007-03-21 18:35:06 UTC (rev 23164)
@@ -235,10 +235,13 @@
 
 #define DO_RUSAGE_SUMMATION 0
 
+#define AUTO_PICK_LEGACY_MACH_LABEL (const char *)(~0)
+
 struct job_s {
 	kq_callback kqjob_callback;
 	SLIST_ENTRY(job_s) sle;
-	SLIST_ENTRY(job_s) hash_sle;
+	SLIST_ENTRY(job_s) pid_hash_sle;
+	SLIST_ENTRY(job_s) label_hash_sle;
 	SLIST_HEAD(, socketgroup) sockets;
 	SLIST_HEAD(, calendarinterval) cal_intervals;
 	SLIST_HEAD(, envitem) global_env;
@@ -283,9 +286,15 @@
 	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, hopefully_exits_last:1, removal_pending:1,
 		     wait4pipe_eof:1, sent_sigkill:1, debug_before_kill:1, weird_bootstrap:1, start_on_mount:1;
-	char label[0];
+	const char label[0];
 };
 
+#define LABEL_HASH_SIZE 53
+
+SLIST_HEAD(, job_s) label_hash[LABEL_HASH_SIZE];
+static size_t hash_label(const char *label);
+
+
 #define job_assumes(j, e)      \
 	                (__builtin_expect(!(e), 0) ? job_log_bug(j, __rcs_file_version__, __FILE__, __LINE__, #e), false : true)
 
@@ -706,9 +715,8 @@
 
 	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);
-	}
+	SLIST_REMOVE(&j->mgr->jobs, j, job_s, sle);
+	SLIST_REMOVE(&label_hash[hash_label(j->label)], j, job_s, label_hash_sle);
 
 	job_log(j, LOG_DEBUG, "Removed");
 
@@ -802,17 +810,13 @@
 {
 	const char **argv = (const char **)mach_cmd2argv(cmd);
 	job_t jr = NULL;
-	char buf[1000];
 
 	if (!job_assumes(j, argv != NULL)) {
 		goto out_bad;
 	}
 
-	/* preflight the string so we know how big it is */
-	snprintf(buf, sizeof(buf), "%s.%s", sizeof(void *) == 8 ? "0xdeadbeeffeedface" : "0xbabecafe", basename((char *)argv[0]));
+	jr = job_new(j->mgr, AUTO_PICK_LEGACY_MACH_LABEL, NULL, argv);
 
-	jr = job_new(j->mgr, buf, NULL, argv);
-
 	free(argv);
 
 	/* jobs can easily be denied creation during shutdown */
@@ -820,8 +824,6 @@
 		goto out_bad;
 	}
 
-	snprintf(jr->label, strlen(jr->label) + 1, "%p.%s", jr, basename(jr->argv[0]));
-
 	jr->mach_uid = uid;
 	jr->ondemand = ond;
 	jr->legacy_mach_job = true;
@@ -861,7 +863,7 @@
 	job_t jr;
 	size_t i;
 
-	if ((jr = jobmgr_find(root_jobmgr, label)) != NULL) {
+	if ((jr = job_find(label)) != NULL) {
 		errno = EEXIST;
 		return NULL;
 	}
@@ -933,7 +935,7 @@
 		jr->anonymous = true;
 		jr->p = anonpid;
 		/* anonymous process reaping is messy */
-		SLIST_INSERT_HEAD(&jm->active_jobs[ACTIVE_JOB_HASH(jr->p)], jr, hash_sle);
+		SLIST_INSERT_HEAD(&jm->active_jobs[ACTIVE_JOB_HASH(jr->p)], jr, pid_hash_sle);
 		job_assumes(jr, kevent_mod(jr->p, EVFILT_PROC, EV_ADD, NOTE_EXIT, 0, root_jobmgr) != -1);
 		job_log(jr, LOG_DEBUG, "Created anonymously.");
 	}
@@ -945,6 +947,8 @@
 job_new(jobmgr_t jm, const char *label, const char *prog, const char *const *argv)
 {
 	const char *const *argv_tmp = argv;
+	char auto_label[1000];
+	char *bn = NULL;
 	char *co;
 	int i, cc = 0;
 	job_t j;
@@ -961,13 +965,23 @@
 		return NULL;
 	}
 
+	if (label == AUTO_PICK_LEGACY_MACH_LABEL) {
+		bn = basename((char *)argv[0]);
+		snprintf(auto_label, sizeof(auto_label), "%s.%s", sizeof(void *) == 8 ? "0xdeadbeeffeedface" : "0xbabecafe", bn);
+		label = auto_label;
+	}
+
 	j = calloc(1, sizeof(struct job_s) + strlen(label) + 1);
 
 	if (!jobmgr_assumes(jm, j != NULL)) {
 		return NULL;
 	}
 
-	strcpy(j->label, label);
+	if (label == auto_label) {
+		snprintf((char *)j->label, strlen(label) + 1, "%p.%s", j, bn);
+	} else {
+		strcpy((char *)j->label, label);
+	}
 	j->kqjob_callback = job_callback;
 	j->mgr = jm;
 	j->min_run_time = LAUNCHD_MIN_JOB_RUN_TIME;
@@ -1008,6 +1022,7 @@
 	}
 
 	SLIST_INSERT_HEAD(&jm->jobs, j, sle);
+	SLIST_INSERT_HEAD(&label_hash[hash_label(j->label)], j, label_hash_sle);
 
 	job_log(j, LOG_DEBUG, "Conceived");
 
@@ -1499,7 +1514,7 @@
 		argv[i] = NULL;
 	}
 
-	if ((j = jobmgr_find(root_jobmgr, label)) != NULL) {
+	if ((j = job_find(label)) != NULL) {
 		errno = EEXIST;
 		return NULL;
 	} else if (label[0] == '\0' || (strncasecmp(label, "", strlen("com.apple.launchd")) == 0) ||
@@ -1518,18 +1533,11 @@
 }
 
 job_t 
-jobmgr_find(jobmgr_t jm, const char *label)
+job_find(const char *label)
 {
-	jobmgr_t jmi;
 	job_t ji;
 
-	SLIST_FOREACH(jmi, &jm->submgrs, sle) {
-		if ((ji = jobmgr_find(jmi, label))) {
-			return ji;
-		}
-	}
-
-	SLIST_FOREACH(ji, &jm->jobs, sle) {
+	SLIST_FOREACH(ji, &label_hash[hash_label(label)], label_hash_sle) {
 		if (strcmp(ji->label, label) == 0) {
 			return ji;
 		}
@@ -1553,7 +1561,7 @@
 
 		hashp = ACTIVE_JOB_HASH(ldc.pid);
 
-		SLIST_FOREACH(ji, &jm->active_jobs[hashp], hash_sle) {
+		SLIST_FOREACH(ji, &jm->active_jobs[hashp], pid_hash_sle) {
 			if (ji->p == ldc.pid) {
 				return ji;
 			}
@@ -1707,7 +1715,7 @@
 	}
 
 	total_children--;
-	SLIST_REMOVE(&j->mgr->active_jobs[ACTIVE_JOB_HASH(j->p)], j, job_s, hash_sle);
+	SLIST_REMOVE(&j->mgr->active_jobs[ACTIVE_JOB_HASH(j->p)], j, job_s, pid_hash_sle);
 
 	job_assumes(j, gettimeofday(&tve, NULL) != -1);
 
@@ -1928,7 +1936,7 @@
 		jobmgr_reap_bulk(jmi, kev);
 	}
 
-	SLIST_FOREACH(ji, &jm->active_jobs[ACTIVE_JOB_HASH(kev->ident)], hash_sle) {
+	SLIST_FOREACH(ji, &jm->active_jobs[ACTIVE_JOB_HASH(kev->ident)], pid_hash_sle) {
 		if (ji->p != (pid_t)kev->ident) {
 			continue;
 		}
@@ -1936,6 +1944,7 @@
 		kev->udata = ji;
 		job_callback(ji, kev);
 
+		/* A given PID exists only once per jobmgr_t */
 		break;
 	}
 }
@@ -2083,7 +2092,7 @@
 		break;
 	default:
 		total_children++;
-		SLIST_INSERT_HEAD(&j->mgr->active_jobs[ACTIVE_JOB_HASH(c)], j, hash_sle);
+		SLIST_INSERT_HEAD(&j->mgr->active_jobs[ACTIVE_JOB_HASH(c)], j, pid_hash_sle);
 
 		if (!j->legacy_mach_job) {
 			job_assumes(j, close(oepair[1]) != -1);
@@ -3562,8 +3571,11 @@
 	}
 
 	if (name) {
+		char thelabel[1000];
+
+		snprintf(thelabel, sizeof(thelabel), "com.apple.launchctl.%s", name);
 		/* no name implies: bootstrap_subset() where creating a "bootstrapper" makes no sense */
-		bootstrapper = job_new(jmr, "com.apple.launchctld", NULL, bootstrap_tool);
+		bootstrapper = job_new(jmr, thelabel, NULL, bootstrap_tool);
 		if (jobmgr_assumes(jmr, bootstrapper != NULL) && (jm || getuid())) {
 			char buf[100];
 
@@ -4713,15 +4725,18 @@
 
 	if (getuid() == 0) {
 		const char *bootstrap_tool[] = { "/bin/launchctl", "bootstrap", "-S", session_type, NULL };
+		char thelabel[1000];
 		job_t bootstrapper;
 
+		snprintf(thelabel, sizeof(thelabel), "com.apple.launchctl.%s", session_type);
+
 		job_assumes(j, (j2 = job_mig_intran2(root_jobmgr, target_subset)) != NULL);
 		j = j2;
 		jobmgr_log(j->mgr, LOG_DEBUG, "Renaming to: %s", session_type);
 		strcpy(j->mgr->name, session_type);
 		job_assumes(j, launchd_mport_deallocate(target_subset) == KERN_SUCCESS);
 
-		bootstrapper = job_new(j->mgr, "com.apple.launchctld", NULL, bootstrap_tool);
+		bootstrapper = job_new(j->mgr, thelabel, NULL, bootstrap_tool);
 		if (job_assumes(j, bootstrapper != NULL)) {
 			job_dispatch(bootstrapper, true);
 		}
@@ -5084,3 +5099,19 @@
 {
 	launchd_assert((root_jobmgr = jobmgr_new(NULL, MACH_PORT_NULL, MACH_PORT_NULL, sflag, getpid() == 1 ? "System" : "Background")) != NULL);
 }
+
+size_t
+hash_label(const char *label)
+{
+	size_t c, r = 5381;
+
+	/* djb2
+	 * This algorithm was first reported by Dan Bernstein many years ago in comp.lang.c
+	 */
+
+	while ((c = *label++)) {
+		r = ((r << 5) + r) + c; /* hash*33 + c */
+	}
+
+	return r % LABEL_HASH_SIZE;
+}

Modified: trunk/launchd/src/launchd_core_logic.h
===================================================================
--- trunk/launchd/src/launchd_core_logic.h	2007-03-21 00:54:01 UTC (rev 23163)
+++ trunk/launchd/src/launchd_core_logic.h	2007-03-21 18:35:06 UTC (rev 23164)
@@ -31,7 +31,6 @@
 void jobmgr_init(bool);
 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);
 jobmgr_t jobmgr_delete_anything_with_port(jobmgr_t jm, mach_port_t port);
 bool jobmgr_ack_port_destruction(jobmgr_t jm, mach_port_t p);
 job_t jobmgr_find_by_service_port(jobmgr_t jm, mach_port_t p);
@@ -39,6 +38,7 @@
 launch_data_t job_export_all(void);
 
 job_t job_dispatch(job_t j, bool kickstart); /* returns j on success, NULL on job removal */
+job_t job_find(const char *label);
 bool job_active(job_t j);
 bool job_is_anonymous(job_t j);
 launch_data_t job_export(job_t j);

Modified: trunk/launchd/src/launchd_unix_ipc.c
===================================================================
--- trunk/launchd/src/launchd_unix_ipc.c	2007-03-21 00:54:01 UTC (rev 23163)
+++ trunk/launchd/src/launchd_unix_ipc.c	2007-03-21 18:35:06 UTC (rev 23164)
@@ -393,19 +393,19 @@
 			launch_data_set_bool(resp, batch_disabler_count == 0);
 		}
 	} else if (!strcmp(cmd, LAUNCH_KEY_STARTJOB)) {
-		if ((j = jobmgr_find(root_jobmgr, launch_data_get_string(data))) != NULL) {
+		if ((j = job_find(launch_data_get_string(data))) != NULL) {
 			job_dispatch(j, true);
 			errno = 0;
 		}
 		resp = launch_data_new_errno(errno);
 	} else if (!strcmp(cmd, LAUNCH_KEY_STOPJOB)) {
-		if ((j = jobmgr_find(root_jobmgr, launch_data_get_string(data))) != NULL) {
+		if ((j = job_find(launch_data_get_string(data))) != NULL) {
 			job_stop(j);
 			errno = 0;
 		}
 		resp = launch_data_new_errno(errno);
 	} else if (!strcmp(cmd, LAUNCH_KEY_REMOVEJOB)) {
-		if ((j = jobmgr_find(root_jobmgr, launch_data_get_string(data))) != NULL) {
+		if ((j = job_find(launch_data_get_string(data))) != NULL) {
 			job_remove(j);
 			errno = 0;
 		}
@@ -428,14 +428,14 @@
 	} else if (!strcmp(cmd, LAUNCH_KEY_SETRESOURCELIMITS)) {
 		resp = adjust_rlimits(data);
 	} else if (!strcmp(cmd, LAUNCH_KEY_GETJOB)) {
-		if ((j = jobmgr_find(root_jobmgr, launch_data_get_string(data))) == NULL) {
+		if ((j = job_find(launch_data_get_string(data))) == NULL) {
 			resp = launch_data_new_errno(errno);
 		} else {
 			resp = job_export(j);
 			ipc_revoke_fds(resp);
 		}
 	} else if (!strcmp(cmd, LAUNCH_KEY_GETJOBWITHHANDLES)) {
-		if ((j = jobmgr_find(root_jobmgr, launch_data_get_string(data))) == NULL) {
+		if ((j = job_find(launch_data_get_string(data))) == NULL) {
 			resp = launch_data_new_errno(errno);
 		} else {
 			resp = job_export(j);

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


More information about the launchd-changes mailing list