xref: /xnu-11417.121.6/osfmk/ipc/ipc_notify.c (revision a1e26a70f38d1d7daa7b49b258e2f8538ad81650)
1 /*
2  * Copyright (c) 2000-2006 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.c
60  *	Author:	Rich Draves
61  *	Date:	1989
62  *
63  *	Notification-sending functions.
64  */
65 
66 #include <mach/port.h>
67 #include <mach/message.h>
68 #include <mach/mach_notify.h>
69 #include <kern/misc_protos.h>
70 #include <kern/ipc_kobject.h>
71 #include <ipc/ipc_notify.h>
72 #include <ipc/ipc_port.h>
73 
74 /*
75  *	Routine:	ipc_notify_port_deleted
76  *	Purpose:
77  *		Send a port-deleted notification.
78  *	Conditions:
79  *		Nothing locked.
80  *		Consumes a ref/soright for port.
81  */
82 
83 void
ipc_notify_port_deleted(ipc_port_t port,mach_port_name_t name)84 ipc_notify_port_deleted(
85 	ipc_port_t              port,
86 	mach_port_name_t        name)
87 {
88 	(void)mach_notify_port_deleted(port, name);
89 	/* send-once right consumed */
90 }
91 
92 /*
93  *	Routine:	ipc_notify_send_possible
94  *	Purpose:
95  *		Send a send-possible notification.
96  *	Conditions:
97  *		Nothing locked.
98  *		Consumes a ref/soright for port.
99  */
100 
101 void
ipc_notify_send_possible(ipc_port_t port,mach_port_name_t name)102 ipc_notify_send_possible(
103 	ipc_port_t              port,
104 	mach_port_name_t        name)
105 {
106 	(void)mach_notify_send_possible(port, name);
107 	/* send-once right consumed */
108 }
109 
110 /*
111  *	Routine:	ipc_notify_port_destroyed
112  *	Purpose:
113  *		Send a port-destroyed notification.
114  *	Conditions:
115  *		Nothing locked.
116  *		Consumes a ref/soright for port.
117  *		Consumes a ref for right, which should be a receive right
118  *		prepped for placement into a message.  (In-transit,
119  *		or in-limbo if a circularity was detected.)
120  */
121 
122 void
ipc_notify_port_destroyed(ipc_port_t port,ipc_port_t right)123 ipc_notify_port_destroyed(
124 	ipc_port_t      port,
125 	ipc_port_t      right)
126 {
127 	mach_notify_port_destroyed(port, right);
128 	/* send-once and receive rights consumed */
129 }
130 
131 /*
132  *	Routine:	ipc_notify_no_senders_prepare
133  *	Purpose:
134  *		Prepare for consuming a no senders notification
135  *		when the port send right count just hit 0.
136  *	Conditions:
137  *		The port is locked.
138  *
139  *		For kobjects (ns_is_kobject), the `ns_notify` port has a reference.
140  *		For regular ports, the `ns_notify` has an outstanding send once right.
141  *	Returns:
142  *		A token that must be passed to ipc_notify_no_senders_emit.
143  */
144 ipc_notify_nsenders_t
ipc_notify_no_senders_prepare(ipc_port_t port)145 ipc_notify_no_senders_prepare(
146 	ipc_port_t              port)
147 {
148 	ipc_notify_nsenders_t req = { };
149 
150 	ip_mq_lock_held(port);
151 
152 	if (port->ip_nsrequest == IP_KOBJECT_NSREQUEST_ARMED) {
153 		port->ip_nsrequest = IP_NULL;
154 
155 		if (ip_active(port)) {
156 			req.ns_notify = port;
157 			req.ns_mscount = port->ip_mscount;
158 			req.ns_is_kobject = true;
159 		} else {
160 			/* silently consume the port-ref */
161 			ip_release_live(port);
162 		}
163 	} else if (port->ip_nsrequest) {
164 		req.ns_notify = port->ip_nsrequest;
165 		req.ns_mscount = port->ip_mscount;
166 		req.ns_is_kobject = false;
167 
168 		port->ip_nsrequest = IP_NULL;
169 	}
170 
171 	return req;
172 }
173 
174 /*
175  *	Routine:	ipc_notify_no_senders
176  *	Purpose:
177  *		Send a no-senders notification.
178  *	Conditions:
179  *		Nothing locked.
180  *		Consumes a ref/soright for port.
181  */
182 
183 void
ipc_notify_no_senders(ipc_port_t port,mach_port_mscount_t mscount,boolean_t kobject)184 ipc_notify_no_senders(
185 	ipc_port_t              port,
186 	mach_port_mscount_t     mscount,
187 	boolean_t               kobject)
188 {
189 	if (kobject) {
190 		ipc_kobject_notify_no_senders(port, mscount);
191 	} else {
192 		(void)mach_notify_no_senders(port, mscount);
193 		/* send-once right consumed */
194 	}
195 }
196 
197 /*
198  *	Routine:	ipc_notify_no_senders_consume
199  *	Purpose:
200  *		Consume a no-senders notification.
201  *	Conditions:
202  *		Nothing locked.
203  *		Consumes a ref/soright for port.
204  */
205 
206 void
ipc_notify_no_senders_consume(ipc_notify_nsenders_t nsrequest)207 ipc_notify_no_senders_consume(
208 	ipc_notify_nsenders_t   nsrequest)
209 {
210 	if (nsrequest.ns_notify) {
211 		if (nsrequest.ns_is_kobject) {
212 			ip_release(nsrequest.ns_notify);
213 		} else {
214 			ipc_port_release_sonce(nsrequest.ns_notify);
215 		}
216 	}
217 }
218 
219 /*
220  *	Routine:	ipc_notify_send_once_and_unlock
221  *	Purpose:
222  *		Send a send-once notification.
223  *	Conditions:
224  *		Port is locked.
225  *		Consumes a ref/soright for port.
226  */
227 
228 void
ipc_notify_send_once_and_unlock(ipc_port_t port)229 ipc_notify_send_once_and_unlock(
230 	ipc_port_t      port)
231 {
232 	if (!ip_active(port)) {
233 		ipc_port_release_sonce_and_unlock(port);
234 	} else if (ip_in_space(port, ipc_space_kernel)) {
235 		ipc_kobject_notify_send_once_and_unlock(port);
236 	} else if (ip_full_kernel(port)) {
237 		ipc_port_release_sonce_and_unlock(port);
238 	} else {
239 		ip_mq_unlock(port);
240 		(void)mach_notify_send_once(port);
241 	}
242 	/* send-once right consumed */
243 }
244 
245 /*
246  *	Routine:	ipc_notify_dead_name
247  *	Purpose:
248  *		Send a dead-name notification.
249  *	Conditions:
250  *		Nothing locked.
251  *		Consumes a ref/soright for port.
252  */
253 
254 void
ipc_notify_dead_name(ipc_port_t port,mach_port_name_t name)255 ipc_notify_dead_name(
256 	ipc_port_t              port,
257 	mach_port_name_t        name)
258 {
259 	(void)mach_notify_dead_name(port, name);
260 	/* send-once right consumed */
261 }
262