[launchd-changes] [22851] trunk/launchd/src
source_changes at macosforge.org
source_changes at macosforge.org
Tue Sep 12 15:46:18 PDT 2006
Revision: 22851
Author: zarzycki at apple.com
Date: 2006-09-12 15:46:16 -0700 (Tue, 12 Sep 2006)
Log Message:
-----------
Part two of the new runtime system.
Modified Paths:
--------------
trunk/launchd/src/launchd_core_logic.c
trunk/launchd/src/launchd_mach_ipc.c
trunk/launchd/src/launchd_runtime.c
trunk/launchd/src/launchd_runtime.h
Modified: trunk/launchd/src/launchd_core_logic.c
===================================================================
--- trunk/launchd/src/launchd_core_logic.c 2006-09-11 21:08:28 UTC (rev 22850)
+++ trunk/launchd/src/launchd_core_logic.c 2006-09-12 22:46:16 UTC (rev 22851)
@@ -293,7 +293,7 @@
watchpath_ignore(j, wp);
SLIST_FOREACH(ms, &j->machservices, sle)
- job_assumes(j, launchd_mport_request_callback(ms->port, NULL, false) == KERN_SUCCESS);
+ job_assumes(j, runtime_remove_mport(ms->port) == KERN_SUCCESS);
}
void
@@ -310,7 +310,7 @@
watchpath_watch(j, wp);
SLIST_FOREACH(ms, &j->machservices, sle)
- job_assumes(j, launchd_mport_request_callback(ms->port, j, false) == KERN_SUCCESS);
+ job_assumes(j, runtime_add_mport(ms->port, NULL, 0) == KERN_SUCCESS);
}
void
@@ -572,10 +572,17 @@
bool
job_setup_machport(job_t j)
{
+ mach_msg_size_t mxmsgsz;
+
if (!job_assumes(j, launchd_mport_create_recv(&j->bs_port) == KERN_SUCCESS))
goto out_bad;
- if (!job_assumes(j, launchd_mport_request_callback(j->bs_port, j, true) == KERN_SUCCESS))
+ /* Sigh... at the moment, MIG has maxsize == sizeof(reply union) */
+ mxmsgsz = sizeof(union __RequestUnion__x_bootstrap_subsystem);
+ if (x_bootstrap_subsystem.maxsize > mxmsgsz)
+ mxmsgsz = x_bootstrap_subsystem.maxsize;
+
+ if (!job_assumes(j, runtime_add_mport(j->bs_port, bootstrap_server, mxmsgsz) == KERN_SUCCESS))
goto out_bad2;
return true;
@@ -2641,6 +2648,7 @@
job_new_bootstrap(job_t p, mach_port_t requestorport, mach_port_t checkin_port)
{
char bslabel[1024] = "100000";
+ mach_msg_size_t mxmsgsz;
job_t j;
if (requestorport == MACH_PORT_NULL) {
@@ -2663,7 +2671,12 @@
sprintf(j->label, "%d", MACH_PORT_INDEX(j->bs_port));
- if (!job_assumes(j, launchd_mport_request_callback(j->bs_port, j, true) == KERN_SUCCESS))
+ /* Sigh... at the moment, MIG has maxsize == sizeof(reply union) */
+ mxmsgsz = sizeof(union __RequestUnion__x_bootstrap_subsystem);
+ if (x_bootstrap_subsystem.maxsize > mxmsgsz)
+ mxmsgsz = x_bootstrap_subsystem.maxsize;
+
+ if (!job_assumes(j, runtime_add_mport(j->bs_port, bootstrap_server, mxmsgsz) == KERN_SUCCESS))
goto out_bad;
if (p) {
Modified: trunk/launchd/src/launchd_mach_ipc.c
===================================================================
--- trunk/launchd/src/launchd_mach_ipc.c 2006-09-11 21:08:28 UTC (rev 22850)
+++ trunk/launchd/src/launchd_mach_ipc.c 2006-09-12 22:46:16 UTC (rev 22851)
@@ -57,7 +57,6 @@
#include "bootstrap_private.h"
#include "bootstrap.h"
#include "bootstrapServer.h"
-#include "launchd_internal.h"
#include "launchd.h"
#include "launchd_runtime.h"
#include "launchd_core_logic.h"
@@ -448,7 +447,7 @@
*reqport = job_get_reqport(j);
*rcvright = job_get_bsport(j);
- launchd_assumes(launchd_mport_request_callback(*rcvright, NULL, true) == KERN_SUCCESS);
+ launchd_assumes(runtime_remove_mport(*rcvright) == KERN_SUCCESS);
launchd_assumes(launchd_mport_make_send(*rcvright) == KERN_SUCCESS);
Modified: trunk/launchd/src/launchd_runtime.c
===================================================================
--- trunk/launchd/src/launchd_runtime.c 2006-09-11 21:08:28 UTC (rev 22850)
+++ trunk/launchd/src/launchd_runtime.c 2006-09-12 22:46:16 UTC (rev 22851)
@@ -57,7 +57,6 @@
#include "launch.h"
#include "launchd.h"
#include "launchd_core_logic.h"
-#include "bootstrapServer.h"
static mach_port_t ipc_port_set = MACH_PORT_NULL;
static mach_port_t demand_port_set = MACH_PORT_NULL;
@@ -66,7 +65,7 @@
static int asynckq = -1;
static pthread_t kqueue_demand_thread;
-static pthread_t demand_thread;;
+static pthread_t demand_thread;
static void *mport_demand_loop(void *arg);
static void *kqueue_demand_loop(void *arg);
@@ -74,9 +73,17 @@
static void async_callback(void);
static kq_callback kqasync_callback = (kq_callback)async_callback;
+static void launchd_runtime2(mach_msg_size_t msg_size, mig_reply_error_t *bufRequest, mig_reply_error_t *bufReply);
+static mach_msg_size_t max_msg_size;
+static mig_callback *mig_cb_table;
+static size_t mig_cb_table_sz;
+static timeout_callback runtime_idle_callback;
+static mach_msg_timeout_t runtime_idle_timeout;
+
void
launchd_runtime_init(void)
{
+ mach_msg_size_t mxmsgsz;
pthread_attr_t attr;
launchd_assert((mainkq = kqueue()) != -1);
@@ -89,8 +96,14 @@
launchd_assert(launchd_mport_create_recv(&launchd_internal_port) == KERN_SUCCESS);
launchd_assert(launchd_mport_make_send(launchd_internal_port) == KERN_SUCCESS);
- launchd_assert((errno = mach_port_move_member(mach_task_self(), launchd_internal_port, ipc_port_set)) == KERN_SUCCESS);
+ /* Sigh... at the moment, MIG has maxsize == sizeof(reply union) */
+ mxmsgsz = sizeof(union __RequestUnion__x_launchd_internal_subsystem);
+ if (x_launchd_internal_subsystem.maxsize > mxmsgsz)
+ mxmsgsz = x_launchd_internal_subsystem.maxsize;
+
+ launchd_assert(runtime_add_mport(launchd_internal_port, launchd_internal_demux, mxmsgsz) == KERN_SUCCESS);
+
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
pthread_attr_setstacksize(&attr, PTHREAD_STACK_MIN);
@@ -193,14 +206,33 @@
void
launchd_runtime(void)
{
- mach_msg_return_t msgr;
+ mig_reply_error_t *req = NULL, *rep = NULL;
+ mach_msg_size_t mz = max_msg_size;
+ kern_return_t kr;
for (;;) {
- msgr = mach_msg_server(launchd_internal_demux, 10*1024, ipc_port_set,
- MACH_RCV_LARGE |
- MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_AUDIT) |
- MACH_RCV_TRAILER_TYPE(MACH_MSG_TRAILER_FORMAT_0));
- launchd_assumes(msgr == MACH_MSG_SUCCESS);
+ kr = vm_allocate(mach_task_self(), (vm_address_t *)&req, mz, VM_MAKE_TAG(VM_MEMORY_MACH_MSG)|TRUE);
+ if (!launchd_assumes(kr == KERN_SUCCESS)) {
+ goto free_path;
+ }
+
+ kr = vm_allocate(mach_task_self(), (vm_address_t *)&rep, mz, VM_MAKE_TAG(VM_MEMORY_MACH_MSG)|TRUE);
+ if (!launchd_assumes(kr == KERN_SUCCESS)) {
+ goto free_path;
+ }
+
+ /* max_msg_size might change, thus phase two... */
+ launchd_runtime2(mz, req, rep);
+
+free_path:
+ if (req) {
+ launchd_assumes(vm_deallocate(mach_task_self(), (vm_address_t)req, mz) == KERN_SUCCESS);
+ req = NULL;
+ }
+ if (rep) {
+ launchd_assumes(vm_deallocate(mach_task_self(), (vm_address_t)rep, mz) == KERN_SUCCESS);
+ rep = NULL;
+ }
}
}
@@ -238,19 +270,55 @@
return errno;
}
+void
+runtime_set_timeout(timeout_callback to_cb, mach_msg_timeout_t to)
+{
+ if (to == 0 || to_cb == NULL) {
+ runtime_idle_callback = NULL;
+ runtime_idle_timeout = 0;
+ }
+
+ runtime_idle_callback = to_cb;
+ runtime_idle_timeout = to;
+}
+
kern_return_t
-launchd_mport_request_callback(mach_port_t name, void *obj, bool readmsg)
+runtime_add_mport(mach_port_t name, mig_callback demux, mach_msg_size_t msg_size)
{
- mach_port_t target_set = MACH_PORT_NULL;
+ size_t needed_table_sz = MACH_PORT_INDEX(name) * 2 * sizeof(mig_callback);
+ mach_port_t target_set = demux ? ipc_port_set : demand_port_set;
- if (obj) {
- target_set = readmsg ? ipc_port_set : demand_port_set;
+ msg_size = round_page(msg_size + MAX_TRAILER_SIZE);
+
+ if (needed_table_sz > mig_cb_table_sz) {
+ mig_callback *new_table = malloc(needed_table_sz);
+
+ if (!launchd_assumes(new_table != NULL))
+ return KERN_RESOURCE_SHORTAGE;
+
+ memcpy(new_table, mig_cb_table, mig_cb_table_sz);
+ memset(new_table + mig_cb_table_sz, 0, needed_table_sz - mig_cb_table_sz);
+
+ mig_cb_table_sz = needed_table_sz;
+ mig_cb_table = new_table;
}
+ mig_cb_table[MACH_PORT_INDEX(name)] = demux;
+
+ if (msg_size > max_msg_size) {
+ max_msg_size = msg_size;
+ }
+
return errno = mach_port_move_member(mach_task_self(), name, target_set);
}
kern_return_t
+runtime_remove_mport(mach_port_t name)
+{
+ return errno = mach_port_move_member(mach_task_self(), name, MACH_PORT_NULL);
+}
+
+kern_return_t
launchd_mport_make_send(mach_port_t name)
{
return errno = mach_port_insert_right(mach_task_self(), name, name, MACH_MSG_TYPE_MAKE_SEND);
@@ -313,19 +381,10 @@
boolean_t
launchd_internal_demux(mach_msg_header_t *Request, mach_msg_header_t *Reply)
{
- if (gc_this_job) {
- job_remove(gc_this_job);
- gc_this_job = NULL;
+ if (launchd_internal_server_routine(Request)) {
+ return launchd_internal_server(Request, Reply);
}
- if (Request->msgh_local_port == launchd_internal_port) {
- if (launchd_internal_server_routine(Request))
- return launchd_internal_server(Request, Reply);
- } else {
- if (bootstrap_server_routine(Request))
- return bootstrap_server(Request, Reply);
- }
-
return notify_server(Request, Reply);
}
@@ -402,3 +461,105 @@
return KERN_SUCCESS;
}
+
+void
+launchd_runtime2(mach_msg_size_t msg_size, mig_reply_error_t *bufRequest, mig_reply_error_t *bufReply)
+{
+ mach_msg_options_t options, tmp_options;
+ mig_reply_error_t *bufTemp;
+ mig_callback the_demux;
+ mach_msg_timeout_t to;
+ mach_msg_return_t mr;
+
+ options = MACH_RCV_MSG|MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_AUDIT) |
+ MACH_RCV_TRAILER_TYPE(MACH_MSG_TRAILER_FORMAT_0);
+
+ tmp_options = options;
+
+ for (;;) {
+ to = MACH_MSG_TIMEOUT_NONE;
+
+ if (msg_size != max_msg_size) {
+ /* The buffer isn't big enougth to receive messages anymore... */
+ tmp_options &= ~MACH_RCV_MSG;
+ options &= ~MACH_RCV_MSG;
+ if (!(tmp_options & MACH_SEND_MSG)) {
+ return;
+ }
+ }
+
+ if ((tmp_options & MACH_RCV_MSG) && runtime_idle_callback) {
+ tmp_options |= MACH_RCV_TIMEOUT;
+
+ if (!(tmp_options & MACH_SEND_TIMEOUT)) {
+ to = runtime_idle_timeout;
+ }
+ }
+
+ mr = mach_msg(&bufReply->Head, tmp_options, bufReply->Head.msgh_size,
+ msg_size, ipc_port_set, to, MACH_PORT_NULL);
+
+ tmp_options = options;
+
+ if (mr == MACH_SEND_INVALID_DEST || mr == MACH_SEND_TIMED_OUT) {
+ /* We need to clean up and start over. */
+ if (bufReply->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) {
+ mach_msg_destroy(&bufReply->Head);
+ }
+ continue;
+ } else if (mr == MACH_RCV_TIMED_OUT) {
+ if (to == MACH_MSG_TIMEOUT_NONE) {
+ continue;
+ }
+ runtime_idle_callback();
+ } else if (!launchd_assumes(mr == MACH_MSG_SUCCESS)) {
+ continue;
+ }
+
+ bufTemp = bufRequest;
+ bufRequest = bufReply;
+ bufReply = bufTemp;
+
+ /* XXX - So very gross */
+ if (gc_this_job) {
+ job_remove(gc_this_job);
+ gc_this_job = NULL;
+ }
+
+ if (!(tmp_options & MACH_RCV_MSG)) {
+ continue;
+ }
+
+ /* we have another request message */
+ the_demux = mig_cb_table[MACH_PORT_INDEX(bufRequest->Head.msgh_local_port)];
+
+ if (!launchd_assumes(the_demux != NULL)) {
+ break;
+ }
+
+ if (the_demux(&bufRequest->Head, &bufReply->Head) == FALSE) {
+ /* XXX - also gross */
+ if (bufRequest->Head.msgh_id == MACH_NOTIFY_NO_SENDERS) {
+ notify_server(&bufRequest->Head, &bufReply->Head);
+ }
+ }
+
+ if (!(bufReply->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX)) {
+ if (bufReply->RetCode == MIG_NO_REPLY) {
+ bufReply->Head.msgh_remote_port = MACH_PORT_NULL;
+ } else if ((bufReply->RetCode != KERN_SUCCESS) && (bufRequest->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX)) {
+ /* destroy the request - but not the reply port */
+ bufRequest->Head.msgh_remote_port = MACH_PORT_NULL;
+ mach_msg_destroy(&bufRequest->Head);
+ }
+ }
+
+ if (bufReply->Head.msgh_remote_port != MACH_PORT_NULL) {
+ tmp_options |= MACH_SEND_MSG;
+
+ if (MACH_MSGH_BITS_REMOTE(bufReply->Head.msgh_bits) != MACH_MSG_TYPE_MOVE_SEND_ONCE) {
+ tmp_options |= MACH_SEND_TIMEOUT;
+ }
+ }
+ }
+}
Modified: trunk/launchd/src/launchd_runtime.h
===================================================================
--- trunk/launchd/src/launchd_runtime.h 2006-09-11 21:08:28 UTC (rev 22850)
+++ trunk/launchd/src/launchd_runtime.h 2006-09-12 22:46:16 UTC (rev 22851)
@@ -38,6 +38,8 @@
void _log_launchd_bug(const char *rcs_rev, const char *path, unsigned int line, const char *test);
typedef void (*kq_callback)(void *, struct kevent *);
+typedef boolean_t (*mig_callback)(mach_msg_header_t *, mach_msg_header_t *);
+typedef void (*timeout_callback)(void);
boolean_t launchd_internal_demux(mach_msg_header_t *Request, mach_msg_header_t *Reply);
@@ -45,6 +47,9 @@
void launchd_runtime(void) __attribute__((noreturn));
void runtime_force_on_demand(bool);
+void runtime_set_timeout(timeout_callback to_cb, mach_msg_timeout_t to);
+kern_return_t runtime_add_mport(mach_port_t name, mig_callback demux, mach_msg_size_t msg_size);
+kern_return_t runtime_remove_mport(mach_port_t name);
int kevent_mod(uintptr_t ident, short filter, u_short flags, u_int fflags, intptr_t data, void *udata);
@@ -52,7 +57,6 @@
kern_return_t launchd_get_bport(mach_port_t *name);
kern_return_t launchd_mport_notify_req(mach_port_t name, mach_msg_id_t which);
kern_return_t launchd_mport_notify_cancel(mach_port_t name, mach_msg_id_t which);
-kern_return_t launchd_mport_request_callback(mach_port_t name, void *obj, bool readmsg);
kern_return_t launchd_mport_create_recv(mach_port_t *name);
kern_return_t launchd_mport_deallocate(mach_port_t name);
kern_return_t launchd_mport_make_send(mach_port_t name);
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/launchd-changes/attachments/20060912/27a8c118/attachment.html
More information about the launchd-changes
mailing list