|
|
1.1 root 1: /*
2: * Mach Operating System
3: * Copyright (c) 1991,1990,1989 Carnegie Mellon University.
4: * Copyright (c) 1993,1994 The University of Utah and
5: * the Computer Systems Laboratory (CSL).
6: * All rights reserved.
7: *
8: * Permission to use, copy, modify and distribute this software and its
9: * documentation is hereby granted, provided that both the copyright
10: * notice and this permission notice appear in all copies of the
11: * software, derivative works or modified versions, and any portions
12: * thereof, and that both notices appear in supporting documentation.
13: *
14: * CARNEGIE MELLON, THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF
15: * THIS SOFTWARE IN ITS "AS IS" CONDITION, AND DISCLAIM ANY LIABILITY
16: * OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF
17: * THIS SOFTWARE.
18: *
19: * Carnegie Mellon requests users of this software to return to
20: *
21: * Software Distribution Coordinator or [email protected]
22: * School of Computer Science
23: * Carnegie Mellon University
24: * Pittsburgh PA 15213-3890
25: *
26: * any improvements or extensions that they make and grant Carnegie Mellon
27: * the rights to redistribute these changes.
28: */
29: /*
30: */
31: /*
32: * File: ipc/ipc_port.h
33: * Author: Rich Draves
34: * Date: 1989
35: *
36: * Definitions for ports.
37: */
38:
39: #ifndef _IPC_IPC_PORT_H_
40: #define _IPC_IPC_PORT_H_
41:
42: #include <mach/boolean.h>
43: #include <mach/kern_return.h>
44: #include <mach/port.h>
45: #include <kern/lock.h>
46: #include <kern/macro_help.h>
47: #include <kern/ipc_kobject.h>
48: #include <ipc/ipc_mqueue.h>
49: #include <ipc/ipc_table.h>
50: #include <ipc/ipc_thread.h>
1.1.1.4 ! root 51: #include <ipc/ipc_object.h>
1.1 root 52: #include "ipc_target.h"
53: #include <mach/rpc.h>
54:
55: /*
56: * A receive right (port) can be in four states:
57: * 1) dead (not active, ip_timestamp has death time)
58: * 2) in a space (ip_receiver_name != 0, ip_receiver points
59: * to the space but doesn't hold a ref for it)
60: * 3) in transit (ip_receiver_name == 0, ip_destination points
61: * to the destination port and holds a ref for it)
62: * 4) in limbo (ip_receiver_name == 0, ip_destination == IP_NULL)
63: *
64: * If the port is active, and ip_receiver points to some space,
65: * then ip_receiver_name != 0, and that space holds receive rights.
66: * If the port is not active, then ip_timestamp contains a timestamp
67: * taken when the port was destroyed.
68: */
69:
70: typedef unsigned int ipc_port_timestamp_t;
71:
72: struct ipc_port {
73: struct ipc_target ip_target;
74:
75: /* This points to the ip_target above if this port isn't on a port set;
76: otherwise it points to the port set's ips_target. */
77: struct ipc_target *ip_cur_target;
78:
79: union {
80: struct ipc_space *receiver;
81: struct ipc_port *destination;
82: ipc_port_timestamp_t timestamp;
83: } data;
84:
85: ipc_kobject_t ip_kobject;
86:
87: mach_port_mscount_t ip_mscount;
88: mach_port_rights_t ip_srights;
89: mach_port_rights_t ip_sorights;
90:
91: struct ipc_port *ip_nsrequest;
92: struct ipc_port *ip_pdrequest;
93: struct ipc_port_request *ip_dnrequests;
94:
95: struct ipc_pset *ip_pset;
96: mach_port_seqno_t ip_seqno; /* locked by message queue */
97: mach_port_msgcount_t ip_msgcount;
98: mach_port_msgcount_t ip_qlimit;
99: struct ipc_thread_queue ip_blocked;
1.1.1.4 ! root 100: unsigned long ip_protected_payload;
1.1 root 101: };
102:
103: #define ip_object ip_target.ipt_object
104: #define ip_receiver_name ip_target.ipt_name
105: #define ip_messages ip_target.ipt_messages
106: #define ip_references ip_object.io_references
107: #define ip_bits ip_object.io_bits
108: #define ip_receiver data.receiver
109: #define ip_destination data.destination
110: #define ip_timestamp data.timestamp
111:
112: #define IP_NULL ((ipc_port_t) IO_NULL)
113: #define IP_DEAD ((ipc_port_t) IO_DEAD)
114:
115: #define IP_VALID(port) IO_VALID(&(port)->ip_object)
116:
117: #define ip_active(port) io_active(&(port)->ip_object)
118: #define ip_lock_init(port) io_lock_init(&(port)->ip_object)
119: #define ip_lock(port) io_lock(&(port)->ip_object)
120: #define ip_lock_try(port) io_lock_try(&(port)->ip_object)
121: #define ip_unlock(port) io_unlock(&(port)->ip_object)
122: #define ip_check_unlock(port) io_check_unlock(&(port)->ip_object)
123: #define ip_reference(port) io_reference(&(port)->ip_object)
124: #define ip_release(port) io_release(&(port)->ip_object)
125:
126: #define ip_alloc() ((ipc_port_t) io_alloc(IOT_PORT))
127: #define ip_free(port) io_free(IOT_PORT, &(port)->ip_object)
128:
129: #define ip_kotype(port) io_kotype(&(port)->ip_object)
130:
131: typedef ipc_table_index_t ipc_port_request_index_t;
132:
133: typedef struct ipc_port_request {
134: union {
135: struct ipc_port *port;
136: ipc_port_request_index_t index;
137: } notify;
138:
139: union {
140: mach_port_t name;
141: struct ipc_table_size *size;
142: } name;
143: } *ipc_port_request_t;
144:
145: #define ipr_next notify.index
146: #define ipr_size name.size
147:
148: #define ipr_soright notify.port
149: #define ipr_name name.name
150:
151: #define IPR_NULL ((ipc_port_request_t) 0)
152:
153: /*
154: * Taking the ipc_port_multiple lock grants the privilege
155: * to lock multiple ports at once. No ports must locked
156: * when it is taken.
157: */
158:
159: decl_simple_lock_data(extern, ipc_port_multiple_lock_data)
160:
161: #define ipc_port_multiple_lock_init() \
162: simple_lock_init(&ipc_port_multiple_lock_data)
163:
164: #define ipc_port_multiple_lock() \
165: simple_lock(&ipc_port_multiple_lock_data)
166:
167: #define ipc_port_multiple_unlock() \
168: simple_unlock(&ipc_port_multiple_lock_data)
169:
170: /*
171: * The port timestamp facility provides timestamps
172: * for port destruction. It is used to serialize
173: * mach_port_names with port death.
174: */
175:
176: decl_simple_lock_data(extern, ipc_port_timestamp_lock_data)
177: extern ipc_port_timestamp_t ipc_port_timestamp_data;
178:
179: #define ipc_port_timestamp_lock_init() \
180: simple_lock_init(&ipc_port_timestamp_lock_data)
181:
182: #define ipc_port_timestamp_lock() \
183: simple_lock(&ipc_port_timestamp_lock_data)
184:
185: #define ipc_port_timestamp_unlock() \
186: simple_unlock(&ipc_port_timestamp_lock_data)
187:
188: extern ipc_port_timestamp_t
1.1.1.3 root 189: ipc_port_timestamp(void);
1.1 root 190:
191: /*
192: * Compares two timestamps, and returns TRUE if one
193: * happened before two. Note that this formulation
194: * works when the timestamp wraps around at 2^32,
195: * as long as one and two aren't too far apart.
196: */
197:
198: #define IP_TIMESTAMP_ORDER(one, two) ((int) ((one) - (two)) < 0)
199:
200: #define ipc_port_translate_receive(space, name, portp) \
201: ipc_object_translate((space), (name), \
202: MACH_PORT_RIGHT_RECEIVE, \
203: (ipc_object_t *) (portp))
204:
205: #define ipc_port_translate_send(space, name, portp) \
206: ipc_object_translate((space), (name), \
207: MACH_PORT_RIGHT_SEND, \
208: (ipc_object_t *) (portp))
209:
210: extern kern_return_t
1.1.1.3 root 211: ipc_port_dnrequest(ipc_port_t, mach_port_t, ipc_port_t,
212: ipc_port_request_index_t *);
1.1 root 213:
214: extern kern_return_t
1.1.1.3 root 215: ipc_port_dngrow(ipc_port_t);
1.1 root 216:
217: extern ipc_port_t
1.1.1.3 root 218: ipc_port_dncancel(ipc_port_t, mach_port_t, ipc_port_request_index_t);
1.1 root 219:
220: #define ipc_port_dnrename(port, index, oname, nname) \
221: MACRO_BEGIN \
222: ipc_port_request_t ipr, table; \
223: \
224: assert(ip_active(port)); \
225: \
226: table = port->ip_dnrequests; \
227: assert(table != IPR_NULL); \
228: \
229: ipr = &table[index]; \
230: assert(ipr->ipr_name == oname); \
231: \
232: ipr->ipr_name = nname; \
233: MACRO_END
234:
235: /* Make a port-deleted request */
236: extern void ipc_port_pdrequest(
237: ipc_port_t port,
238: ipc_port_t notify,
239: ipc_port_t *previousp);
240:
241: /* Make a no-senders request */
242: extern void ipc_port_nsrequest(
243: ipc_port_t port,
244: mach_port_mscount_t sync,
245: ipc_port_t notify,
246: ipc_port_t *previousp);
247:
248: /* Change a port's queue limit */
249: extern void ipc_port_set_qlimit(
250: ipc_port_t port,
251: mach_port_msgcount_t qlimit);
252:
253: #define ipc_port_set_mscount(port, mscount) \
254: MACRO_BEGIN \
255: assert(ip_active(port)); \
256: \
257: (port)->ip_mscount = (mscount); \
258: MACRO_END
259:
260: extern struct ipc_mqueue *
1.1.1.3 root 261: ipc_port_lock_mqueue(ipc_port_t);
1.1 root 262:
263: extern void
1.1.1.3 root 264: ipc_port_set_seqno(ipc_port_t, mach_port_seqno_t);
1.1 root 265:
266: extern void
1.1.1.4 ! root 267: ipc_port_set_protected_payload(ipc_port_t, unsigned long);
! 268:
! 269: extern void
! 270: ipc_port_clear_protected_payload(ipc_port_t);
! 271:
! 272: extern void
1.1.1.3 root 273: ipc_port_clear_receiver(ipc_port_t);
1.1 root 274:
275: extern void
1.1.1.3 root 276: ipc_port_init(ipc_port_t, ipc_space_t, mach_port_t);
1.1 root 277:
278: extern kern_return_t
1.1.1.3 root 279: ipc_port_alloc(ipc_space_t, mach_port_t *, ipc_port_t *);
1.1 root 280:
281: extern kern_return_t
1.1.1.3 root 282: ipc_port_alloc_name(ipc_space_t, mach_port_t, ipc_port_t *);
1.1 root 283:
284: extern void
1.1.1.3 root 285: ipc_port_destroy(ipc_port_t);
1.1 root 286:
287: extern boolean_t
1.1.1.3 root 288: ipc_port_check_circularity(ipc_port_t, ipc_port_t);
1.1 root 289:
290: extern ipc_port_t
1.1.1.3 root 291: ipc_port_lookup_notify(ipc_space_t, mach_port_t);
1.1 root 292:
293: extern ipc_port_t
1.1.1.3 root 294: ipc_port_make_send(ipc_port_t);
1.1 root 295:
296: extern ipc_port_t
1.1.1.3 root 297: ipc_port_copy_send(ipc_port_t);
1.1 root 298:
299: extern mach_port_t
1.1.1.3 root 300: ipc_port_copyout_send(ipc_port_t, ipc_space_t);
1.1 root 301:
302: extern void
1.1.1.3 root 303: ipc_port_release_send(ipc_port_t);
1.1 root 304:
305: extern ipc_port_t
1.1.1.3 root 306: ipc_port_make_sonce(ipc_port_t);
1.1 root 307:
308: extern void
1.1.1.3 root 309: ipc_port_release_sonce(ipc_port_t);
1.1 root 310:
311: extern void
1.1.1.3 root 312: ipc_port_release_receive(ipc_port_t);
1.1 root 313:
314: extern ipc_port_t
1.1.1.3 root 315: ipc_port_alloc_special(ipc_space_t);
1.1 root 316:
317: extern void
1.1.1.3 root 318: ipc_port_dealloc_special(ipc_port_t, ipc_space_t);
1.1 root 319:
320: #define ipc_port_alloc_kernel() \
321: ipc_port_alloc_special(ipc_space_kernel)
322: #define ipc_port_dealloc_kernel(port) \
323: ipc_port_dealloc_special((port), ipc_space_kernel)
324:
325: #define ipc_port_alloc_reply() \
326: ipc_port_alloc_special(ipc_space_reply)
327: #define ipc_port_dealloc_reply(port) \
328: ipc_port_dealloc_special((port), ipc_space_reply)
329:
330: #define ipc_port_reference(port) \
331: ipc_object_reference(&(port)->ip_object)
332:
333: #define ipc_port_release(port) \
334: ipc_object_release(&(port)->ip_object)
335:
1.1.1.4 ! root 336: static inline boolean_t
! 337: ipc_port_flag_protected_payload(const struct ipc_port *port)
! 338: {
! 339: return !! (port->ip_target.ipt_object.io_bits
! 340: & IO_BITS_PROTECTED_PAYLOAD);
! 341: }
! 342:
! 343: static inline void
! 344: ipc_port_flag_protected_payload_set(struct ipc_port *port)
! 345: {
! 346: port->ip_target.ipt_object.io_bits |= IO_BITS_PROTECTED_PAYLOAD;
! 347: }
! 348:
! 349: static inline void
! 350: ipc_port_flag_protected_payload_clear(struct ipc_port *port)
! 351: {
! 352: port->ip_target.ipt_object.io_bits &= ~IO_BITS_PROTECTED_PAYLOAD;
! 353: }
! 354:
1.1.1.2 root 355: #endif /* _IPC_IPC_PORT_H_ */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.