static void host_notify_all( host_flavor_t notify_type, mach_msg_header_t *msg, mach_msg_size_t msg_size) { queue_t notify_queue = &host_notify_queue[notify_type]; lck_mtx_lock(&host_notify_lock); if (!queue_empty(notify_queue)) { queue_head_t send_queue; host_notify_t entry; send_queue = *notify_queue; queue_init(notify_queue); send_queue.next->prev = &send_queue; send_queue.prev->next = &send_queue; msg->msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE, 0); msg->msgh_local_port = MACH_PORT_NULL; msg->msgh_id = host_notify_replyid[notify_type]; msg->msgh_reserved = 0; while ((entry = (host_notify_t)dequeue(&send_queue)) != NULL) { ipc_port_t port; port = entry->port; assert(port != IP_NULL); ip_lock(port); assert(ip_kotype(port) == IKOT_HOST_NOTIFY); assert(port->ip_kobject == (ipc_kobject_t)entry); ipc_kobject_set_atomically(port, IKO_NULL, IKOT_NONE); ip_unlock(port); lck_mtx_unlock(&host_notify_lock); zfree(host_notify_zone, entry); msg->msgh_remote_port = port; (void) mach_msg_send_from_kernel_proper(msg, msg_size); lck_mtx_lock(&host_notify_lock); } } lck_mtx_unlock(&host_notify_lock); }
static void mk_timer_expire( void *p0, __unused void *p1) { mk_timer_t timer = p0; ipc_port_t port; simple_lock(&timer->lock); if (timer->active > 1) { timer->active--; simple_unlock(&timer->lock); return; } port = timer->port; assert(port != IP_NULL); assert(timer->active == 1); while (timer->is_armed && timer->active == 1) { mk_timer_expire_msg_t msg; timer->is_armed = FALSE; simple_unlock(&timer->lock); msg.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0); msg.header.msgh_remote_port = port; msg.header.msgh_local_port = MACH_PORT_NULL; msg.header.msgh_reserved = msg.header.msgh_id = 0; msg.unused[0] = msg.unused[1] = msg.unused[2] = 0; (void) mach_msg_send_from_kernel_proper(&msg.header, sizeof (msg)); simple_lock(&timer->lock); } if (--timer->active == 0 && timer->is_dead) { simple_unlock(&timer->lock); zfree(mk_timer_zone, timer); ipc_port_release_send(port); return; } simple_unlock(&timer->lock); }