FreeBSD/Linux Kernel Cross Reference
sys/ipc/ipc_port.h
1 /*
2 * Mach Operating System
3 * Copyright (c) 1993,1992,1991,1990,1989 Carnegie Mellon University
4 * All Rights Reserved.
5 *
6 * Permission to use, copy, modify and distribute this software and its
7 * documentation is hereby granted, provided that both the copyright
8 * notice and this permission notice appear in all copies of the
9 * software, derivative works or modified versions, and any portions
10 * thereof, and that both notices appear in supporting documentation.
11 *
12 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
13 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15 *
16 * Carnegie Mellon requests users of this software to return to
17 *
18 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
19 * School of Computer Science
20 * Carnegie Mellon University
21 * Pittsburgh PA 15213-3890
22 *
23 * any improvements or extensions that they make and grant Carnegie Mellon
24 * the rights to redistribute these changes.
25 */
26 /*
27 * HISTORY
28 * $Log: ipc_port.h,v $
29 * Revision 2.15 93/11/17 17:00:41 dbg
30 * Moved declaration of ipc_port_t to ipc/ipc_types.h to avoid
31 * circular include file chains. Added ANSI function prototypes.
32 * [93/03/30 dbg]
33 *
34 * Revision 2.14 92/04/06 01:16:28 rpd
35 * Fixed ip_msgcount overflow problem by changing it
36 * and ip_qlimit to be mach_port_msgcount_t.
37 * Added ipc_port_lock_mqueue.
38 * [92/04/06 rpd]
39 *
40 * Revision 2.13 92/03/10 16:26:18 jsb
41 * Merged in norma branch changes as of NORMA_MK7:
42 * Removed token-related fields. Added fields for receive-right migration
43 * and xmm support. Added ip_nsproxy* macros for no-senders support.
44 * [92/03/09 13:14:35 jsb]
45 *
46 * Revision 2.12 91/12/14 14:28:26 jsb
47 * NORMA_IPC: replaced dummy port struct fields with real names.
48 *
49 * Revision 2.11 91/11/14 16:56:20 rpd
50 * Added ipc_fields.h hack, with fields in struct ipc_port to match.
51 * Added IP_NORMA_IS_PROXY macro.
52 * [91/11/00 jsb]
53 *
54 * Revision 2.10 91/10/09 16:10:01 af
55 * Added (unconditional) ipc_port_print declaration.
56 * [91/09/02 rpd]
57 *
58 * Revision 2.9 91/08/28 11:13:50 jsb
59 * Added ip_seqno and ipc_port_set_seqno.
60 * [91/08/09 rpd]
61 * Renamed clport (now ip_norma) fields in struct ipc_port.
62 * [91/08/14 19:31:55 jsb]
63 *
64 * Revision 2.8 91/08/03 18:18:37 jsb
65 * Fixed include. Added clport fields directly to struct ipc_port.
66 * [91/07/17 14:06:25 jsb]
67 *
68 * Revision 2.7 91/06/17 15:46:26 jsb
69 * Renamed NORMA conditionals.
70 * [91/06/17 10:44:06 jsb]
71 *
72 * Revision 2.6 91/05/14 16:35:34 mrt
73 * Correcting copyright
74 *
75 * Revision 2.5 91/02/05 17:23:10 mrt
76 * Changed to new Mach copyright
77 * [91/02/01 15:50:04 mrt]
78 *
79 * Revision 2.4 90/11/05 14:29:39 rpd
80 * Added ipc_port_reference, ipc_port_release.
81 * [90/10/29 rpd]
82 *
83 * Revision 2.3 90/09/28 16:55:18 jsb
84 * Added NORMA_IPC support.
85 * [90/09/28 14:03:58 jsb]
86 *
87 * Revision 2.2 90/06/02 14:51:13 rpd
88 * Created for new IPC.
89 * [90/03/26 21:01:25 rpd]
90 *
91 */
92 /*
93 * File: ipc/ipc_port.h
94 * Author: Rich Draves
95 * Date: 1989
96 *
97 * Definitions for ports.
98 */
99
100 #ifndef _IPC_IPC_PORT_H_
101 #define _IPC_IPC_PORT_H_
102
103 #include <mach_ipc_compat.h>
104 #include <norma_ipc.h>
105
106 #include <mach/boolean.h>
107 #include <mach/kern_return.h>
108 #include <mach/port.h>
109 #include <kern/lock.h>
110 #include <kern/macro_help.h>
111 #include <kern/ipc_kobject.h>
112 #include <ipc/ipc_types.h>
113 #include <ipc/ipc_object.h>
114 #include <ipc/ipc_mqueue.h>
115 #include <ipc/ipc_table.h>
116 #include <ipc/ipc_thread.h>
117
118 /*
119 * A receive right (port) can be in four states:
120 * 1) dead (not active, ip_timestamp has death time)
121 * 2) in a space (ip_receiver_name != 0, ip_receiver points
122 * to the space but doesn't hold a ref for it)
123 * 3) in transit (ip_receiver_name == 0, ip_destination points
124 * to the destination port and holds a ref for it)
125 * 4) in limbo (ip_receiver_name == 0, ip_destination == IP_NULL)
126 *
127 * If the port is active, and ip_receiver points to some space,
128 * then ip_receiver_name != 0, and that space holds receive rights.
129 * If the port is not active, then ip_timestamp contains a timestamp
130 * taken when the port was destroyed.
131 */
132
133 typedef unsigned int ipc_port_timestamp_t;
134
135 struct ipc_port {
136 struct ipc_object ip_object;
137
138 union {
139 struct ipc_space *receiver;
140 struct ipc_port *destination;
141 ipc_port_timestamp_t timestamp;
142 } data;
143 mach_port_t ip_receiver_name;
144
145 ipc_kobject_t ip_kobject;
146
147 mach_port_mscount_t ip_mscount;
148 mach_port_rights_t ip_srights;
149 mach_port_rights_t ip_sorights;
150
151 struct ipc_port *ip_nsrequest;
152 struct ipc_port *ip_pdrequest;
153 struct ipc_port_request *ip_dnrequests;
154
155 struct ipc_pset *ip_pset;
156 mach_port_seqno_t ip_seqno; /* locked by message queue */
157 mach_port_msgcount_t ip_msgcount;
158 mach_port_msgcount_t ip_qlimit;
159 struct ipc_mqueue ip_messages;
160 struct ipc_thread_queue ip_blocked;
161
162 #if NORMA_IPC
163 unsigned long ip_norma_uid;
164 unsigned long ip_norma_dest_node;
165 long ip_norma_stransit;
166 long ip_norma_sotransit;
167 long ip_norma_xmm_object_refs;
168 boolean_t ip_norma_is_proxy;
169 boolean_t ip_norma_is_special;
170 struct ipc_port *ip_norma_atrium;
171 struct ipc_port *ip_norma_queue_next;
172 struct ipc_port *ip_norma_xmm_object;
173 struct ipc_port *ip_norma_next;
174 long ip_norma_spare1;
175 long ip_norma_spare2;
176 long ip_norma_spare3;
177 long ip_norma_spare4;
178 #endif /* NORMA_IPC */
179 };
180
181 #define ip_references ip_object.io_references
182 #define ip_bits ip_object.io_bits
183 #define ip_receiver data.receiver
184 #define ip_destination data.destination
185 #define ip_timestamp data.timestamp
186
187 #define IP_NULL ((ipc_port_t) IO_NULL)
188 #define IP_DEAD ((ipc_port_t) IO_DEAD)
189
190 #define IP_VALID(port) IO_VALID(&(port)->ip_object)
191
192 #define ip_active(port) io_active(&(port)->ip_object)
193 #define ip_lock_init(port) io_lock_init(&(port)->ip_object)
194 #define ip_lock(port) io_lock(&(port)->ip_object)
195 #define ip_lock_try(port) io_lock_try(&(port)->ip_object)
196 #define ip_unlock(port) io_unlock(&(port)->ip_object)
197 #define ip_check_unlock(port) io_check_unlock(&(port)->ip_object)
198 #define ip_reference(port) io_reference(&(port)->ip_object)
199 #define ip_release(port) io_release(&(port)->ip_object)
200
201 #define ip_alloc() ((ipc_port_t) io_alloc(IOT_PORT))
202 #define ip_free(port) io_free(IOT_PORT, &(port)->ip_object)
203
204 #define ip_kotype(port) io_kotype(&(port)->ip_object)
205
206 typedef ipc_table_index_t ipc_port_request_index_t;
207
208 typedef struct ipc_port_request {
209 union {
210 struct ipc_port *port;
211 ipc_port_request_index_t index;
212 } notify;
213
214 union {
215 mach_port_t name;
216 struct ipc_table_size *size;
217 } name;
218 } *ipc_port_request_t;
219
220 #define ipr_next notify.index
221 #define ipr_size name.size
222
223 #define ipr_soright notify.port
224 #define ipr_name name.name
225
226 #define IPR_NULL ((ipc_port_request_t) 0)
227
228 #if MACH_IPC_COMPAT
229 /*
230 * For backwards compatibility, the ip_pdrequest field can hold a
231 * send right instead of a send-once right. This is indicated by
232 * the low bit of the pointer. This works because the zone package
233 * guarantees that the two low bits of port pointers are zero.
234 */
235
236 #define ip_pdsendp(soright) ((unsigned int)(soright) & 1)
237 #define ip_pdsend(soright) ((ipc_port_t)((unsigned int)(soright) &~ 1))
238 #define ip_pdsendm(sright) ((ipc_port_t)((unsigned int)(sright) | 1))
239
240 /*
241 * For backwards compatibility, the ipr_soright field can hold
242 * a space pointer. This is indicated by the low bit of the pointer.
243 * This works because the zone package guarantees that the two low
244 * bits of port and space pointers are zero.
245 */
246
247 #define ipr_spacep(soright) ((unsigned int)(soright) & 1)
248 #define ipr_space(soright) ((ipc_space_t)((unsigned int)(soright) &~ 1))
249 #define ipr_spacem(space) ((ipc_port_t)((unsigned int)(space) | 1))
250 #endif /* MACH_IPC_COMPAT */
251
252 /*
253 * Taking the ipc_port_multiple lock grants the privilege
254 * to lock multiple ports at once. No ports must locked
255 * when it is taken.
256 */
257
258 decl_simple_lock_data(extern, ipc_port_multiple_lock_data)
259
260 #define ipc_port_multiple_lock_init() \
261 simple_lock_init(&ipc_port_multiple_lock_data)
262
263 #define ipc_port_multiple_lock() \
264 simple_lock(&ipc_port_multiple_lock_data)
265
266 #define ipc_port_multiple_unlock() \
267 simple_unlock(&ipc_port_multiple_lock_data)
268
269 /*
270 * The port timestamp facility provides timestamps
271 * for port destruction. It is used to serialize
272 * mach_port_names with port death.
273 */
274
275 decl_simple_lock_data(extern, ipc_port_timestamp_lock_data)
276 extern ipc_port_timestamp_t ipc_port_timestamp_data;
277
278 #define ipc_port_timestamp_lock_init() \
279 simple_lock_init(&ipc_port_timestamp_lock_data)
280
281 #define ipc_port_timestamp_lock() \
282 simple_lock(&ipc_port_timestamp_lock_data)
283
284 #define ipc_port_timestamp_unlock() \
285 simple_unlock(&ipc_port_timestamp_lock_data)
286
287 extern ipc_port_timestamp_t
288 ipc_port_timestamp(void);
289
290 /*
291 * Compares two timestamps, and returns TRUE if one
292 * happened before two. Note that this formulation
293 * works when the timestamp wraps around at 2^32,
294 * as long as one and two aren't too far apart.
295 */
296
297 #define IP_TIMESTAMP_ORDER(one, two) ((int) ((one) - (two)) < 0)
298
299 #define ipc_port_translate_receive(space, name, portp) \
300 ipc_object_translate((space), (name), \
301 MACH_PORT_RIGHT_RECEIVE, \
302 (ipc_object_t *) (portp))
303
304 #define ipc_port_translate_send(space, name, portp) \
305 ipc_object_translate((space), (name), \
306 MACH_PORT_RIGHT_SEND, \
307 (ipc_object_t *) (portp))
308
309 extern kern_return_t
310 ipc_port_dnrequest(
311 ipc_port_t port,
312 mach_port_t name,
313 ipc_port_t soright,
314 ipc_port_request_index_t *indexp);
315
316 extern kern_return_t
317 ipc_port_dngrow(
318 ipc_port_t port);
319
320 extern ipc_port_t
321 ipc_port_dncancel(
322 ipc_port_t port,
323 mach_port_t name,
324 ipc_port_request_index_t index);
325
326 #define ipc_port_dnrename(port, index, oname, nname) \
327 MACRO_BEGIN \
328 ipc_port_request_t ipr, table; \
329 \
330 assert(ip_active(port)); \
331 \
332 table = port->ip_dnrequests; \
333 assert(table != IPR_NULL); \
334 \
335 ipr = &table[index]; \
336 assert(ipr->ipr_name == oname); \
337 \
338 ipr->ipr_name = nname; \
339 MACRO_END
340
341 extern void
342 ipc_port_pdrequest(
343 ipc_port_t port,
344 ipc_port_t notify,
345 ipc_port_t *previousp);
346
347 extern void
348 ipc_port_nsrequest(
349 ipc_port_t port,
350 mach_port_mscount_t sync,
351 ipc_port_t notify,
352 ipc_port_t *previousp);
353
354 extern void
355 ipc_port_set_qlimit(
356 ipc_port_t port,
357 mach_port_msgcount_t qlimit);
358
359 #define ipc_port_set_mscount(port, mscount) \
360 MACRO_BEGIN \
361 assert(ip_active(port)); \
362 \
363 (port)->ip_mscount = (mscount); \
364 MACRO_END
365
366 extern struct ipc_mqueue *
367 ipc_port_lock_mqueue(ipc_port_t);
368
369 extern void
370 ipc_port_set_seqno(ipc_port_t, mach_port_seqno_t);
371
372 extern void
373 ipc_port_clear_receiver(ipc_port_t);
374
375 extern void
376 ipc_port_init(
377 ipc_port_t port,
378 ipc_space_t space,
379 mach_port_t name);
380
381 extern kern_return_t
382 ipc_port_alloc(
383 ipc_space_t space,
384 mach_port_t *namep,
385 ipc_port_t *portp);
386
387 extern kern_return_t
388 ipc_port_alloc_name(
389 ipc_space_t space,
390 mach_port_t name,
391 ipc_port_t *portp);
392
393 extern void
394 ipc_port_destroy(ipc_port_t);
395
396 extern boolean_t
397 ipc_port_check_circularity(
398 ipc_port_t port,
399 ipc_port_t dest);
400
401 extern ipc_port_t
402 ipc_port_lookup_notify(ipc_space_t, mach_port_t);
403
404 extern ipc_port_t
405 ipc_port_make_send(ipc_port_t);
406
407 extern ipc_port_t
408 ipc_port_copy_send(ipc_port_t);
409
410 extern mach_port_t
411 ipc_port_copyout_send(ipc_port_t, ipc_space_t);
412
413 extern void
414 ipc_port_release_send(ipc_port_t);
415
416 extern ipc_port_t
417 ipc_port_make_sonce(ipc_port_t);
418
419 extern void
420 ipc_port_release_sonce(ipc_port_t);
421
422 extern void
423 ipc_port_release_receive(ipc_port_t);
424
425 extern ipc_port_t
426 ipc_port_alloc_special(ipc_space_t);
427
428 extern void
429 ipc_port_dealloc_special(ipc_port_t, ipc_space_t);
430
431 #define ipc_port_alloc_kernel() \
432 ipc_port_alloc_special(ipc_space_kernel)
433 #define ipc_port_dealloc_kernel(port) \
434 ipc_port_dealloc_special((port), ipc_space_kernel)
435
436 #define ipc_port_alloc_reply() \
437 ipc_port_alloc_special(ipc_space_reply)
438 #define ipc_port_dealloc_reply(port) \
439 ipc_port_dealloc_special((port), ipc_space_reply)
440
441 #define ipc_port_reference(port) \
442 ipc_object_reference(&(port)->ip_object)
443
444 #define ipc_port_release(port) \
445 ipc_object_release(&(port)->ip_object)
446
447 #if MACH_IPC_COMPAT
448
449 extern kern_return_t
450 ipc_port_alloc_compat(ipc_space_t, mach_port_t *, ipc_port_t *);
451
452 extern mach_port_t
453 ipc_port_copyout_send_compat(ipc_port_t, ipc_space_t);
454
455 extern mach_port_t
456 ipc_port_copyout_receiver(ipc_port_t, ipc_space_t);
457
458 #endif /* MACH_IPC_COMPAT */
459
460 extern void
461 ipc_port_print(ipc_port_t);
462
463 #if NORMA_IPC
464
465 #define IP_NORMA_IS_PROXY(port) ((port)->ip_norma_is_proxy)
466
467 /*
468 * A proxy never has a real nsrequest, but is always has a fake
469 * nsrequest so that the norma ipc system is notified when there
470 * are no send rights for a proxy. A fake nsrequest is indicated by
471 * the low bit of the pointer. This works because the zone package
472 * guarantees that the two low bits of port pointers are zero.
473 */
474
475 #define ip_nsproxyp(nsrequest) ((unsigned int)(nsrequest) & 1)
476 #define ip_nsproxy(nsrequest) ((ipc_port_t)((unsigned int)(nsrequest) &~ 1))
477 #define ip_nsproxym(proxy) ((ipc_port_t)((unsigned int)(proxy) | 1))
478
479 #endif /* NORMA_IPC */
480
481 #endif /* _IPC_IPC_PORT_H_ */
Cache object: 9503bf587c0257e3247c90b3438baa27
|