#include <kern/kern_types.h>
#include <vm/vm_map.h>
+#include <libkern/section_keywords.h>
/*
* Routine: ipc_pset_alloc
#include <sys/event.h>
#include <sys/errno.h>
-static int filt_machportattach(struct knote *kn);
+static int filt_machportattach(struct knote *kn, struct kevent_internal_s *kev);
static void filt_machportdetach(struct knote *kn);
static int filt_machport(struct knote *kn, long hint);
static int filt_machporttouch(struct knote *kn, struct kevent_internal_s *kev);
static int filt_machportprocess(struct knote *kn, struct filt_process_s *data, struct kevent_internal_s *kev);
static unsigned filt_machportpeek(struct knote *kn);
-struct filterops machport_filtops = {
- .f_attach = filt_machportattach,
- .f_detach = filt_machportdetach,
- .f_event = filt_machport,
- .f_touch = filt_machporttouch,
- .f_process = filt_machportprocess,
+SECURITY_READ_ONLY_EARLY(struct filterops) machport_filtops = {
+ .f_adjusts_qos = 1,
+ .f_attach = filt_machportattach,
+ .f_detach = filt_machportdetach,
+ .f_event = filt_machport,
+ .f_touch = filt_machporttouch,
+ .f_process = filt_machportprocess,
.f_peek = filt_machportpeek,
};
static int
filt_machportattach(
- struct knote *kn)
+ 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);
__IGNORE_WCASTALIGN(pset = (ipc_pset_t)entry->ie_object);
mqueue = &pset->ips_messages;
+ ips_reference(pset);
imq_lock(mqueue);
+ kn->kn_ptr.p_mqueue = mqueue;
/*
* Bind the portset wait queue directly to knote/kqueue.
*/
error = knote_link_waitq(kn, &mqueue->imq_wait_queue, &wq_link_id);
if (!error) {
- ips_reference(pset);
- kn->kn_ptr.p_mqueue = mqueue;
KNOTE_ATTACH(&mqueue->imq_klist, kn);
+ imq_unlock(mqueue);
+
+ }
+ else {
+ kn->kn_ptr.p_mqueue = IMQ_NULL;
+ imq_unlock(mqueue);
+ ips_release(pset);
}
- imq_unlock(mqueue);
is_read_unlock(space);
kn->kn_ptr.p_mqueue = mqueue;
KNOTE_ATTACH(&mqueue->imq_klist, kn);
if ((first = ipc_kmsg_queue_first(&mqueue->imq_messages)) != IKM_NULL) {
+ int sync_qos_override_index = ipc_port_get_max_sync_qos_index(port);
if (kn->kn_sfflags & MACH_RCV_MSG)
- knote_adjust_qos(kn, first->ikm_qos, first->ikm_qos_override);
+ knote_adjust_qos(kn, first->ikm_qos, first->ikm_qos_override,
+ sync_qos_override_index);
result = 1;
}
imq_unlock(mqueue);
} else if (imq_is_valid(mqueue)) {
assert(!imq_is_set(mqueue));
if ((first = ipc_kmsg_queue_first(&mqueue->imq_messages)) != IKM_NULL) {
+ ipc_port_t port = ip_from_mq(mqueue);
+ int sync_qos_override_index = ipc_port_get_max_sync_qos_index(port);
+
if (kn->kn_sfflags & MACH_RCV_MSG)
- knote_adjust_qos(kn, first->ikm_qos, first->ikm_qos_override);
+ knote_adjust_qos(kn, first->ikm_qos, first->ikm_qos_override,
+ sync_qos_override_index);
result = 1;
}
}
*/
if (imq_is_valid(mqueue) && !imq_is_set(mqueue) &&
(first = ipc_kmsg_queue_first(&mqueue->imq_messages)) != IKM_NULL) {
+ ipc_port_t port = ip_from_mq(mqueue);
+ int sync_qos_override_index = ipc_port_get_max_sync_qos_index(port);
+
if (kn->kn_sfflags & MACH_RCV_MSG)
- knote_adjust_qos(kn, first->ikm_qos, first->ikm_qos_override);
+ knote_adjust_qos(kn, first->ikm_qos, first->ikm_qos_override,
+ sync_qos_override_index);
result = 1;
} else if (kn->kn_sfflags & MACH_RCV_MSG) {
knote_adjust_qos(kn,
MACH_MSG_PRIORITY_UNSPECIFIED,
- MACH_MSG_PRIORITY_UNSPECIFIED);
+ MACH_MSG_PRIORITY_UNSPECIFIED,
+ THREAD_QOS_UNSPECIFIED);
}
imq_unlock(mqueue);
self->ith_continuation = NULL;
option |= MACH_RCV_TIMEOUT; // never wait
self->ith_state = MACH_RCV_IN_PROGRESS;
+ self->ith_knote = kn;
wresult = ipc_mqueue_receive_on_thread(
mqueue,