[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