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 *imq_inheritor_knote; 117 struct turnstile *imq_inheritor_turnstile; 118 thread_t imq_inheritor_thread_ref; 119 thread_t 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_option_t option, 163 mach_msg_timeout_t timeout_val); 164 165 /* check for queue send queue full of a port */ 166 extern mach_msg_return_t ipc_mqueue_preflight_send( 167 ipc_mqueue_t mqueue, 168 ipc_kmsg_t kmsg, 169 mach_msg_option_t option, 170 mach_msg_timeout_t timeout_val); 171 172 /* Set a [send-possible] override on the mqueue */ 173 extern void ipc_mqueue_override_send_locked( 174 ipc_mqueue_t mqueue, 175 mach_msg_qos_t qos_ovr); 176 177 /* Receive a message from a message queue */ 178 extern void ipc_mqueue_receive( 179 waitq_t waitq, 180 mach_msg_option64_t option64, 181 mach_msg_size_t max_size, 182 mach_msg_size_t max_aux_size, 183 mach_msg_timeout_t timeout_val, 184 int interruptible, 185 bool has_continuation); 186 187 /* Receive a message from a message queue using a specified thread */ 188 extern wait_result_t ipc_mqueue_receive_on_thread_and_unlock( 189 waitq_t waitq, 190 mach_msg_option64_t option64, 191 mach_msg_size_t max_size, 192 mach_msg_size_t max_aux_size, 193 mach_msg_timeout_t rcv_timeout, 194 int interruptible, 195 thread_t thread); 196 197 /* Continuation routine for message receive */ 198 extern void ipc_mqueue_receive_continue( 199 void *param, 200 wait_result_t wresult); 201 202 /* Select a message from a queue and try to post it to ourself */ 203 extern void ipc_mqueue_select_on_thread_locked( 204 ipc_mqueue_t port_mq, 205 mach_msg_option64_t option64, 206 mach_msg_size_t max_size, 207 mach_msg_size_t max_aux_size, 208 thread_t thread); 209 210 /* Peek into a messaqe queue to see if there are messages */ 211 extern unsigned ipc_mqueue_peek( 212 ipc_mqueue_t mqueue, 213 mach_port_seqno_t *msg_seqnop, 214 mach_msg_size_t *msg_sizep, 215 mach_msg_id_t *msg_idp, 216 mach_msg_max_trailer_t *msg_trailerp, 217 ipc_kmsg_t *kmsgp); 218 219 /* Peek into a locked messaqe queue to see if there are messages */ 220 extern unsigned ipc_mqueue_peek_locked( 221 ipc_mqueue_t mqueue, 222 mach_port_seqno_t *msg_seqnop, 223 mach_msg_size_t *msg_sizep, 224 mach_msg_id_t *msg_idp, 225 mach_msg_max_trailer_t *msg_trailerp, 226 ipc_kmsg_t *kmsgp); 227 228 #if MACH_FLIPC 229 /* Release an mqueue/port reference that was granted by MACH64_PEEK_MSG */ 230 extern void ipc_mqueue_release_peek_ref( 231 ipc_mqueue_t mqueue); 232 #endif /* MACH_FLIPC */ 233 234 /* Clear a message count reservation */ 235 extern void ipc_mqueue_release_msgcount( 236 ipc_mqueue_t port_mq); 237 238 /* Change a queue limit */ 239 extern void ipc_mqueue_set_qlimit_locked( 240 ipc_mqueue_t mqueue, 241 mach_port_msgcount_t qlimit); 242 243 /* Change a queue's sequence number */ 244 extern void ipc_mqueue_set_seqno_locked( 245 ipc_mqueue_t mqueue, 246 mach_port_seqno_t seqno); 247 248 /* Convert a name in a space to a message queue */ 249 extern mach_msg_return_t ipc_mqueue_copyin( 250 ipc_space_t space, 251 mach_port_name_t name, 252 ipc_object_t *objectp); 253 254 /* Safe to use the klist ptr */ 255 extern bool 256 ipc_port_has_klist( 257 ipc_port_t port); 258 259 #endif /* _IPC_IPC_MQUEUE_H_ */ 260