1 /*
2 * Copyright (c) 2000 Apple Computer, 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_notify.h
60 * Author: Rich Draves
61 * Date: 1989
62 *
63 * Declarations of notification-sending functions.
64 */
65
66 #ifndef _IPC_IPC_NOTIFY_H_
67 #define _IPC_IPC_NOTIFY_H_
68
69 #include <mach/port.h>
70
71 __BEGIN_DECLS __ASSUME_PTR_ABI_SINGLE_BEGIN
72 #pragma GCC visibility push(hidden)
73
74
75 typedef struct ipc_notify_nsenders {
76 ipc_port_t ns_notify;
77 mach_port_mscount_t ns_mscount;
78 boolean_t ns_is_kobject;
79 } ipc_notify_nsenders_t;
80
81
82 /*!
83 * @abstract
84 * Send a dead-name notification.
85 *
86 * @discussion
87 * A dead-name notification is sent when the port being monitored
88 * has its receive right destroyed.
89 *
90 * Conditions:
91 * - Nothing locked.
92 * - Consumes a ref/soright for @c notify.
93 *
94 * @param notify The port receiving the notification.
95 * @param name The name for the port whose receive right has been
96 * destroyed.
97 */
98 extern void ipc_notify_dead_name(
99 ipc_port_t notify,
100 mach_port_name_t name);
101
102 /*!
103 * @abstract
104 * Send a send-possible notification.
105 *
106 * @discussion
107 * A send-possible notification is sent when the port being monitored
108 * has a message queue that becomes non full, and messages can be sent
109 * to it without blocking.
110 *
111 * This consumes the dead-name/send-possible notification slot for this port.
112 *
113 * Conditions:
114 * - Nothing locked.
115 * - Consumes a ref/soright for @c notify.
116 *
117 * @param notify The port receiving the notification.
118 * @param name The name for the port which can now receive messages
119 * without blocking.
120 */
121 extern void ipc_notify_send_possible(
122 ipc_port_t notify,
123 mach_port_name_t name);
124
125 /*!
126 * @abstract
127 * Send a port-deleted notification.
128 *
129 * @discussion
130 * A port-deleted notification is sent whenever the last send(-once) right
131 * which has an active dead-name/send-possible notification armed is removed
132 * from the space.
133 *
134 * Conditions:
135 * - Nothing locked.
136 * - Consumes a ref/soright for notify.
137 *
138 * @param notify The port receiving the notification.
139 * @param name The name for the port which has been removed from the
140 * space.
141 */
142 extern void ipc_notify_port_deleted(
143 ipc_port_t notify,
144 mach_port_name_t name);
145
146 /*!
147 * @abstract
148 * Send a port-destroyed notification.
149 *
150 * @discussion
151 * A port-destroyed notification allows for a task to get a receive right
152 * back instead of it being destroyed.
153 *
154 * Conditions:
155 * - Nothing locked.
156 * - Consumes a ref/soright for @c notify.
157 * - Consumes a ref for @c right, which should be a receive right
158 * prepped for placement into a message. (In-transit, or in-limbo if
159 * a circularity was detected.)
160 *
161 * @param notify The port receiving the notification.
162 * @param right The receive right being sent back.
163 */
164 extern void ipc_notify_port_destroyed(
165 ipc_port_t notify,
166 ipc_port_t right);
167
168 /*!
169 * @abstract
170 * Send a no-senders notification to a regular message queue port.
171 *
172 * @discussion
173 * Condition:
174 * - Nothing locked.
175 * - Consumes a ref/soright for @c notify.
176 *
177 * @param notify The port receiving the notification.
178 * @param mscount The make-send count at the time this notification
179 * was sent (it can be used to synchronize new rights
180 * being made by the client concurrently).
181 */
182 extern void ipc_notify_no_senders_mqueue(
183 ipc_port_t notify,
184 mach_port_mscount_t mscount);
185
186 /*!
187 * @abstract
188 * Send a no-senders notification to a kobject port.
189 *
190 * @discussion
191 * Condition:
192 * - Nothing locked.
193 * - Consumes a port reference to @c notify.
194 *
195 * @param notify The port receiving the notification,
196 * which is also the port for which the notification
197 * is being emitted.
198 * @param mscount The make-send count at the time this notification
199 * was sent (it can be used to synchronize new rights
200 * being made by the client concurrently).
201 */
202 extern void ipc_notify_no_senders_kobject(
203 ipc_port_t notify,
204 mach_port_mscount_t mscount);
205
206 /*!
207 * @abstract
208 * Prepare for consuming a no-senders notification
209 * when the port send right count just hit 0.
210 *
211 * @discussion
212 * This allows for a two-phase prepare/emit because sending the no-senders
213 * notification requires no lock to be held.
214 *
215 * @c ipc_notify_no_senders_emit() must be called on the value returned
216 * by this function.
217 *
218 * Conditions:
219 * - @c port is locked.
220 *
221 * For kobjects (ns_is_kobject), the `ns_notify` port has a port reference.
222 * For regular ports, the `ns_notify` has an outstanding send once right.
223 *
224 * @returns
225 * A token that must be passed to ipc_notify_no_senders_emit.
226 */
227 extern ipc_notify_nsenders_t ipc_notify_no_senders_prepare(
228 ipc_port_t port);
229
230 /*!
231 * @abstract
232 * Emits a no-senders notification that was prepared by
233 * @c ipc_notify_no_senders_prepare().
234 */
235 static inline void
ipc_notify_no_senders_emit(ipc_notify_nsenders_t nsrequest)236 ipc_notify_no_senders_emit(ipc_notify_nsenders_t nsrequest)
237 {
238 if (!nsrequest.ns_notify) {
239 /* nothing to do */
240 } else if (nsrequest.ns_is_kobject) {
241 ipc_notify_no_senders_kobject(nsrequest.ns_notify,
242 nsrequest.ns_mscount);
243 } else {
244 ipc_notify_no_senders_mqueue(nsrequest.ns_notify,
245 nsrequest.ns_mscount);
246 }
247 }
248
249 /* Send a send-once notification */
250 /*!
251 * @abstract
252 * Send a send-once notification.
253 *
254 * @discussion
255 * A send-once notification is sent when a send-once right to @c port is being
256 * destroyed without any message having been sent to it.
257 *
258 * Conditions:
259 * - @c port is locked.
260 * - Consumes a ref/soright for @c port.
261 */
262 extern void ipc_notify_send_once_and_unlock(
263 ipc_port_t port);
264
265
266 #pragma GCC visibility pop
267 __ASSUME_PTR_ABI_SINGLE_END __END_DECLS
268
269 #endif /* _IPC_IPC_NOTIFY_H_ */
270