* Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- *
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* unlawful or unlicensed copies of an Apple operating system, or to
* circumvent, violate, or enable the circumvention or violation of, any
* terms of an Apple operating system software license agreement.
- *
+ *
* Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this file.
- *
+ *
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
- *
+ *
* @APPLE_OSREFERENCE_LICENSE_HEADER_END@
*/
/*
* @OSF_COPYRIGHT@
*/
-/*
+/*
* Mach Operating System
* Copyright (c) 1991,1990,1989 Carnegie Mellon University
* All Rights Reserved.
- *
+ *
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
- *
+ *
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
+ *
* Carnegie Mellon requests users of this software to return to
- *
+ *
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
- *
+ *
* any improvements or extensions that they make and grant Carnegie Mellon
* the rights to redistribute these changes.
*/
kern_return_t
ipc_pset_alloc(
- ipc_space_t space,
- mach_port_name_t *namep,
- ipc_pset_t *psetp)
+ ipc_space_t space,
+ mach_port_name_t *namep,
+ ipc_pset_t *psetp)
{
ipc_pset_t pset;
mach_port_name_t name;
kern_return_t kr;
kr = ipc_object_alloc(space, IOT_PORT_SET,
- MACH_PORT_TYPE_PORT_SET, 0,
- &name, (ipc_object_t *) &pset);
+ MACH_PORT_TYPE_PORT_SET, 0,
+ &name, (ipc_object_t *) &pset);
if (kr != KERN_SUCCESS) {
return kr;
}
kern_return_t
ipc_pset_alloc_name(
- ipc_space_t space,
- mach_port_name_t name,
- ipc_pset_t *psetp)
+ ipc_space_t space,
+ mach_port_name_t name,
+ ipc_pset_t *psetp)
{
ipc_pset_t pset;
kern_return_t kr;
kr = ipc_object_alloc_name(space, IOT_PORT_SET,
- MACH_PORT_TYPE_PORT_SET, 0,
- name, (ipc_object_t *) &pset);
+ MACH_PORT_TYPE_PORT_SET, 0,
+ name, (ipc_object_t *) &pset);
if (kr != KERN_SUCCESS) {
return kr;
}
*/
boolean_t
ipc_pset_member(
- ipc_pset_t pset,
- ipc_port_t port)
+ ipc_pset_t pset,
+ ipc_port_t port)
{
assert(ip_active(port));
- return (ipc_mqueue_member(&port->ip_messages, &pset->ips_messages));
+ return ipc_mqueue_member(&port->ip_messages, &pset->ips_messages);
}
kern_return_t
ipc_pset_add(
- ipc_pset_t pset,
- ipc_port_t port,
- uint64_t *reserved_link,
- uint64_t *reserved_prepost)
+ ipc_pset_t pset,
+ ipc_port_t port,
+ uint64_t *reserved_link,
+ uint64_t *reserved_prepost)
{
kern_return_t kr;
assert(ip_active(port));
kr = ipc_mqueue_add(&port->ip_messages, &pset->ips_messages,
- reserved_link, reserved_prepost);
+ reserved_link, reserved_prepost);
return kr;
}
kern_return_t
ipc_pset_remove(
- ipc_pset_t pset,
- ipc_port_t port)
+ ipc_pset_t pset,
+ ipc_port_t port)
{
kern_return_t kr;
assert(ip_active(port));
-
- if (port->ip_in_pset == 0)
+
+ if (port->ip_in_pset == 0) {
return KERN_NOT_IN_SET;
+ }
kr = ipc_mqueue_remove(&port->ip_messages, &pset->ips_messages);
ipc_pset_t pset;
kr = ipc_right_lookup_read(space, psname, &entry);
- if (kr != KERN_SUCCESS)
+ if (kr != KERN_SUCCESS) {
return kr;
+ }
/* space is read-locked and active */
if ((entry->ie_bits & MACH_PORT_TYPE_PORT_SET) == 0) {
kern_return_t
ipc_pset_remove_from_all(
- ipc_port_t port)
+ ipc_port_t port)
{
- if (port->ip_in_pset == 0)
+ if (port->ip_in_pset == 0) {
return KERN_NOT_IN_SET;
+ }
- /*
+ /*
* Remove the port's mqueue from all sets
*/
ipc_mqueue_remove_from_all(&port->ip_messages);
void
ipc_pset_destroy(
- ipc_pset_t pset)
+ ipc_space_t space,
+ ipc_pset_t pset)
{
assert(ips_active(pset));
* discover the change.
*/
imq_lock(&pset->ips_messages);
- ipc_mqueue_changed(&pset->ips_messages);
+ ipc_mqueue_changed(space, &pset->ips_messages);
imq_unlock(&pset->ips_messages);
ipc_mqueue_deinit(&pset->ips_messages);
struct turnstile *ts = filt_machport_kqueue_turnstile(kn);
if (!ts) {
- if (link) *link = PORT_SYNC_LINK_NO_LINKAGE;
+ if (link) {
+ *link = PORT_SYNC_LINK_NO_LINKAGE;
+ }
} else if (kn->kn_ext[3] == 0) {
ip_reference(port);
kn->kn_ext[3] = (uintptr_t)port;
- if (link) *link = PORT_SYNC_LINK_WORKLOOP_KNOTE;
+ if (link) {
+ *link = PORT_SYNC_LINK_WORKLOOP_KNOTE;
+ }
} else {
ts = (struct turnstile *)kn->kn_hook;
- if (link) *link = PORT_SYNC_LINK_WORKLOOP_STASH;
+ if (link) {
+ *link = PORT_SYNC_LINK_WORKLOOP_STASH;
+ }
}
return ts;
*/
void
filt_machport_turnstile_prepare_lazily(
- struct knote *kn,
- mach_msg_type_name_t msgt_name,
- ipc_port_t port)
+ struct knote *kn,
+ mach_msg_type_name_t msgt_name,
+ ipc_port_t port)
{
/* This is called from within filt_machportprocess */
assert((kn->kn_status & KN_SUPPRESSED) && (kn->kn_status & KN_LOCKED));
struct turnstile *ts = filt_machport_kqueue_turnstile(kn);
- if (ts == TURNSTILE_NULL || kn->kn_ext[3] == 0 || kn->kn_hook)
+ if (ts == TURNSTILE_NULL || kn->kn_ext[3] == 0 || kn->kn_hook) {
return;
+ }
if ((msgt_name == MACH_MSG_TYPE_PORT_SEND_ONCE && port->ip_specialreply) ||
- (msgt_name == MACH_MSG_TYPE_PORT_RECEIVE)) {
+ (msgt_name == MACH_MSG_TYPE_PORT_RECEIVE)) {
struct turnstile *kn_ts = turnstile_alloc();
kn_ts = turnstile_prepare((uintptr_t)kn,
- (struct turnstile **)&kn->kn_hook, kn_ts, TURNSTILE_KNOTE);
+ (struct turnstile **)&kn->kn_hook, kn_ts, TURNSTILE_KNOTE);
turnstile_update_inheritor(kn_ts, ts,
- TURNSTILE_IMMEDIATE_UPDATE | TURNSTILE_INHERITOR_TURNSTILE);
+ TURNSTILE_IMMEDIATE_UPDATE | TURNSTILE_INHERITOR_TURNSTILE);
turnstile_cleanup();
}
}
* neuter the linkage.
*/
if (port->ip_sync_link_state == PORT_SYNC_LINK_WORKLOOP_KNOTE &&
- port->ip_sync_inheritor_knote == kn) {
+ port->ip_sync_inheritor_knote == kn) {
ipc_port_adjust_special_reply_port_locked(port, NULL,
- (IPC_PORT_ADJUST_SR_NONE | IPC_PORT_ADJUST_SR_ENABLE_EVENT), FALSE);
+ (IPC_PORT_ADJUST_SR_NONE | IPC_PORT_ADJUST_SR_ENABLE_EVENT), FALSE);
} else {
ip_unlock(port);
}
}
if (ts) {
turnstile_update_inheritor(ts, TURNSTILE_INHERITOR_NULL,
- TURNSTILE_IMMEDIATE_UPDATE);
+ TURNSTILE_IMMEDIATE_UPDATE);
turnstile_reference(ts);
}
imq_unlock(mqueue);
ts = kn->kn_hook;
turnstile_update_inheritor(ts, TURNSTILE_INHERITOR_NULL,
- TURNSTILE_IMMEDIATE_UPDATE);
+ TURNSTILE_IMMEDIATE_UPDATE);
turnstile_update_inheritor_complete(ts, TURNSTILE_INTERLOCK_HELD);
turnstile_complete((uintptr_t)kn, (struct turnstile **)&kn->kn_hook, &ts);
static int
filt_machportattach(
- struct knote *kn,
- __unused struct kevent_internal_s *kev)
+ struct knote *kn,
+ __unused struct kevent_internal_s *kev)
{
mach_port_name_t name = (mach_port_name_t)kn->kn_kevent.ident;
uint64_t wq_link_id = waitq_link_reserve(NULL);
* need an indication of their fired state to be returned
* from the attach operation.
*/
-
} else if (entry->ie_bits & MACH_PORT_TYPE_RECEIVE) {
ipc_port_t port;
if (send_turnstile) {
turnstile_reference(send_turnstile);
turnstile_update_inheritor(send_turnstile, turnstile,
- (TURNSTILE_INHERITOR_TURNSTILE | TURNSTILE_IMMEDIATE_UPDATE));
+ (TURNSTILE_INHERITOR_TURNSTILE | TURNSTILE_IMMEDIATE_UPDATE));
}
if ((first = ipc_kmsg_queue_first(&mqueue->imq_messages)) != IKM_NULL) {
is_read_unlock(space);
if (send_turnstile) {
turnstile_update_inheritor_complete(send_turnstile,
- TURNSTILE_INTERLOCK_NOT_HELD);
+ TURNSTILE_INTERLOCK_NOT_HELD);
turnstile_deallocate(send_turnstile);
}
is_read_unlock(space);
error = ENOTSUP;
}
- } else {
+ } else {
error = ENOENT;
}
if (send_turnstile) {
turnstile_reference(send_turnstile);
turnstile_update_inheritor(send_turnstile,
- ipc_port_get_inheritor(port),
- TURNSTILE_INHERITOR_TURNSTILE | TURNSTILE_IMMEDIATE_UPDATE);
+ ipc_port_get_inheritor(port),
+ TURNSTILE_INHERITOR_TURNSTILE | TURNSTILE_IMMEDIATE_UPDATE);
}
}
if (send_turnstile) {
turnstile_update_inheritor_complete(send_turnstile,
- TURNSTILE_INTERLOCK_NOT_HELD);
+ TURNSTILE_INTERLOCK_NOT_HELD);
turnstile_deallocate(send_turnstile);
}
* the message is to be direct-received, we adjust the
* QoS of the knote according the requested and override
* QoS of that first message.
- *
- * NOTE_REVOKE events are a legacy way to indicate that the port/portset
- * was deallocated or left the current Mach portspace (modern technique
- * is with an EV_VANISHED protocol). If we see NOTE_REVOKE, deliver an
- * EV_EOF event for these changes (hopefully it will get delivered before
- * the port name recycles to the same generation count and someone tries
- * to re-register a kevent for it or the events are udata-specific -
- * avoiding a conflict).
*/
static int
-filt_machportevent(
- struct knote *kn,
- long hint)
+filt_machportevent(struct knote *kn, long hint __assert_only)
{
ipc_mqueue_t mqueue = kn->kn_ptr.p_mqueue;
ipc_kmsg_t first;
/* mqueue locked by caller */
assert(imq_held(mqueue));
-
- if (hint == NOTE_REVOKE) {
- kn->kn_flags |= EV_EOF | EV_ONESHOT;
- result = FILTER_ACTIVE | FILTER_RESET_EVENT_QOS;
- } else if (imq_is_valid(mqueue)) {
+ assert(hint != NOTE_REVOKE);
+ if (imq_is_valid(mqueue)) {
assert(!imq_is_set(mqueue));
if ((first = ipc_kmsg_queue_first(&mqueue->imq_messages)) != IKM_NULL) {
result = FILTER_ACTIVE | filt_machport_adjust_qos(kn, first);
wait_result_t wresult;
mach_msg_option_t option;
mach_vm_address_t addr;
- mach_msg_size_t size;
+ mach_msg_size_t size;
/* Capture current state */
*kev = kn->kn_kevent;
* provided, just force a MACH_RCV_TOO_LARGE to detect the
* name of the port and sizeof the waiting message.
*/
- option = kn->kn_sfflags & (MACH_RCV_MSG|MACH_RCV_LARGE|MACH_RCV_LARGE_IDENTITY|
- MACH_RCV_TRAILER_MASK|MACH_RCV_VOUCHER);
+ option = kn->kn_sfflags & (MACH_RCV_MSG | MACH_RCV_LARGE | MACH_RCV_LARGE_IDENTITY |
+ MACH_RCV_TRAILER_MASK | MACH_RCV_VOUCHER);
if (option & MACH_RCV_MSG) {
addr = (mach_vm_address_t) kn->kn_ext[0];
addr = (mach_vm_address_t)process_data->fp_data_out;
size = (mach_msg_size_t)process_data->fp_data_resid;
option |= (MACH_RCV_LARGE | MACH_RCV_LARGE_IDENTITY);
- if (process_data->fp_flags & KEVENT_FLAG_STACK_DATA)
+ if (process_data->fp_flags & KEVENT_FLAG_STACK_DATA) {
option |= MACH_RCV_STACK;
+ }
}
} else {
/* just detect the port name (if a set) and size of the first message */
self->ith_knote = kn;
wresult = ipc_mqueue_receive_on_thread(
- mqueue,
- option,
- size, /* max_size */
- 0, /* immediate timeout */
- THREAD_INTERRUPTIBLE,
- self);
+ mqueue,
+ option,
+ size, /* max_size */
+ 0, /* immediate timeout */
+ THREAD_INTERRUPTIBLE,
+ self);
/* mqueue unlocked */
/*
*/
if (kev->fflags == MACH_RCV_TOO_LARGE) {
kev->ext[1] = self->ith_msize;
- if (option & MACH_RCV_LARGE_IDENTITY)
+ if (option & MACH_RCV_LARGE_IDENTITY) {
kev->data = self->ith_receiver_name;
- else
+ } else {
kev->data = MACH_PORT_NULL;
+ }
} else {
kev->ext[1] = size;
kev->data = MACH_PORT_NULL;
} else {
assert(option & MACH_RCV_STACK);
kev->ext[0] = process_data->fp_data_out +
- process_data->fp_data_resid;
+ process_data->fp_data_resid;
}
}
*/
if (kev->fflags == MACH_MSG_SUCCESS) {
kev->ext[2] = ((uint64_t)self->ith_qos << 32) |
- (uint64_t)self->ith_qos_override;
+ (uint64_t)self->ith_qos_override;
}
return FILTER_ACTIVE;