xref: /xnu-12377.81.4/osfmk/ipc/ipc_notify.h (revision 043036a2b3718f7f0be807e2870f8f47d3fa0796) !
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