1 /* 2 * Copyright (c) 2000-2007 Apple Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28 /* 29 * @OSF_COPYRIGHT@ 30 */ 31 /* 32 * Mach Operating System 33 * Copyright (c) 1991,1990,1989 Carnegie Mellon University 34 * All Rights Reserved. 35 * 36 * Permission to use, copy, modify and distribute this software and its 37 * documentation is hereby granted, provided that both the copyright 38 * notice and this permission notice appear in all copies of the 39 * software, derivative works or modified versions, and any portions 40 * thereof, and that both notices appear in supporting documentation. 41 * 42 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 43 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 44 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 45 * 46 * Carnegie Mellon requests users of this software to return to 47 * 48 * Software Distribution Coordinator or [email protected] 49 * School of Computer Science 50 * Carnegie Mellon University 51 * Pittsburgh PA 15213-3890 52 * 53 * any improvements or extensions that they make and grant Carnegie Mellon 54 * the rights to redistribute these changes. 55 */ 56 /* 57 */ 58 /* 59 * File: ipc/ipc_mqueue.h 60 * Author: Rich Draves 61 * Date: 1989 62 * 63 * Definitions for message queues. 64 */ 65 66 #ifndef _IPC_IPC_MQUEUE_H_ 67 #define _IPC_IPC_MQUEUE_H_ 68 69 #include <mach_assert.h> 70 71 #include <mach/message.h> 72 73 #include <kern/assert.h> 74 #include <kern/macro_help.h> 75 #include <kern/kern_types.h> 76 #include <kern/waitq.h> 77 78 #include <ipc/ipc_kmsg.h> 79 #include <ipc/ipc_object.h> 80 #include <ipc/ipc_types.h> 81 82 #include <sys/event.h> 83 84 /* this type doesn't exist and is only used to do math */ 85 struct ipc_object_waitq { 86 struct ipc_object iowq_object; 87 struct waitq iowq_waitq; 88 }; 89 90 typedef struct ipc_mqueue { 91 circle_queue_head_t imq_messages; 92 mach_port_seqno_t imq_seqno; 93 mach_port_name_t imq_receiver_name; 94 uint16_t imq_msgcount; 95 uint16_t imq_qlimit; 96 /* 97 * The imq_context structure member fills in a 32-bit padding gap 98 * in ipc_mqueue. 99 */ 100 uint32_t imq_context; 101 #if MACH_FLIPC 102 struct flipc_port *imq_fport; // Null for local port, or ptr to flipc port 103 #endif 104 union { 105 /* 106 * Special Reply Ports (ip_specialreply == true): 107 * only use imq_srp_owner_thread 108 * 109 * Ports, based on ip_sync_link_state, use: 110 * - PORT_SYNC_LINK_ANY: imq_klist 111 * - PORT_SYNC_LINK_WORKLOOP_KNOTE: imq_inheritor_knote 112 * - PORT_SYNC_LINK_WORKLOOP_STASH: imq_inheritor_turnstile (has a +1) 113 * - PORT_SYNC_LINK_RCV_THREAD: imq_inheritor_thread_ref 114 */ 115 struct klist imq_klist; 116 struct knote *XNU_PTRAUTH_SIGNED_PTR("ipc_mqueue.knote") imq_inheritor_knote; 117 struct turnstile *XNU_PTRAUTH_SIGNED_PTR("ipc_mqueue.turnstile") imq_inheritor_turnstile; 118 thread_t XNU_PTRAUTH_SIGNED_PTR("ipc_mqueue.thread_ref") imq_inheritor_thread_ref; 119 thread_t XNU_PTRAUTH_SIGNED_PTR("ipc_mqueue.srp_owner_thread") imq_srp_owner_thread; 120 }; 121 } *ipc_mqueue_t; 122 123 #define IMQ_NULL ((ipc_mqueue_t) 0) 124 125 #define imq_full(mq) ((mq)->imq_msgcount >= (mq)->imq_qlimit) 126 #define imq_full_kernel(mq) ((mq)->imq_msgcount >= MACH_PORT_QLIMIT_KERNEL) 127 128 extern int ipc_mqueue_full; 129 // extern int ipc_mqueue_rcv; 130 131 #define IPC_MQUEUE_FULL CAST_EVENT64_T(&ipc_mqueue_full) 132 #define IPC_MQUEUE_RECEIVE NO_EVENT64 133 134 /* 135 * Exported interfaces 136 */ 137 138 /* Initialize a newly-allocated message queue */ 139 extern void ipc_mqueue_init( 140 ipc_mqueue_t mqueue); 141 142 /* destroy an mqueue */ 143 extern boolean_t ipc_mqueue_destroy_locked( 144 ipc_mqueue_t mqueue, 145 waitq_link_list_t *free_l); 146 147 /* Wake up receivers waiting in a message queue */ 148 extern void ipc_mqueue_changed( 149 ipc_space_t space, 150 waitq_t waitq); 151 152 /* Add the specific mqueue as a member of the set */ 153 extern kern_return_t ipc_mqueue_add_locked( 154 ipc_mqueue_t mqueue, 155 ipc_pset_t pset, 156 waitq_link_t *linkp); 157 158 /* Send a message to a port */ 159 extern mach_msg_return_t ipc_mqueue_send_locked( 160 ipc_mqueue_t mqueue, 161 ipc_kmsg_t kmsg, 162 mach_msg_option64_t option, 163 mach_msg_timeout_t timeout_val); 164 165 /* Set a [send-possible] override on the mqueue */ 166 extern void ipc_mqueue_override_send_locked( 167 ipc_mqueue_t mqueue, 168 mach_msg_qos_t qos_ovr); 169 170 /* Receive a message from a message queue */ 171 extern void ipc_mqueue_receive( 172 waitq_t waitq, 173 mach_msg_timeout_t timeout_val, 174 int interruptible, 175 thread_t thread, 176 bool has_continuation); 177 178 /* Receive a message from a message queue using a specified thread */ 179 extern wait_result_t ipc_mqueue_receive_on_thread_and_unlock( 180 waitq_t waitq, 181 mach_msg_timeout_t rcv_timeout, 182 int interruptible, 183 thread_t thread); 184 185 /* Continuation routine for message receive */ 186 extern void ipc_mqueue_receive_continue( 187 void *param, 188 wait_result_t wresult); 189 190 /* Select a message from a queue and try to post it to ourself */ 191 extern void ipc_mqueue_select_on_thread_locked( 192 ipc_mqueue_t port_mq, 193 mach_msg_option64_t option64, 194 thread_t thread); 195 196 /* Peek into a messaqe queue to see if there are messages */ 197 extern unsigned ipc_mqueue_peek( 198 ipc_mqueue_t mqueue, 199 mach_port_seqno_t *msg_seqnop, 200 mach_msg_size_t *msg_sizep, 201 mach_msg_id_t *msg_idp, 202 mach_msg_max_trailer_t *msg_trailerp, 203 ipc_kmsg_t *kmsgp); 204 205 /* Peek into a locked messaqe queue to see if there are messages */ 206 extern unsigned ipc_mqueue_peek_locked( 207 ipc_mqueue_t mqueue, 208 mach_port_seqno_t *msg_seqnop, 209 mach_msg_size_t *msg_sizep, 210 mach_msg_id_t *msg_idp, 211 mach_msg_max_trailer_t *msg_trailerp, 212 ipc_kmsg_t *kmsgp); 213 214 #if MACH_FLIPC 215 /* Release an mqueue/port reference that was granted by MACH64_PEEK_MSG */ 216 extern void ipc_mqueue_release_peek_ref( 217 ipc_mqueue_t mqueue); 218 #endif /* MACH_FLIPC */ 219 220 /* Clear a message count reservation */ 221 extern void ipc_mqueue_release_msgcount( 222 ipc_mqueue_t port_mq); 223 224 /* Change a queue limit */ 225 extern void ipc_mqueue_set_qlimit_locked( 226 ipc_mqueue_t mqueue, 227 mach_port_msgcount_t qlimit); 228 229 /* Change a queue's sequence number */ 230 extern void ipc_mqueue_set_seqno_locked( 231 ipc_mqueue_t mqueue, 232 mach_port_seqno_t seqno); 233 234 /* Convert a name in a space to a message queue */ 235 extern mach_msg_return_t ipc_mqueue_copyin( 236 ipc_space_t space, 237 mach_port_name_t name, 238 ipc_object_t *objectp); 239 240 /* Safe to use the klist ptr */ 241 extern bool 242 ipc_port_has_klist( 243 ipc_port_t port); 244 245 #endif /* _IPC_IPC_MQUEUE_H_ */ 246