|
|
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>
51: #include "ipc_target.h"
52: #include <mach/rpc.h>
53:
54: /*
55: * A receive right (port) can be in four states:
56: * 1) dead (not active, ip_timestamp has death time)
57: * 2) in a space (ip_receiver_name != 0, ip_receiver points
58: * to the space but doesn't hold a ref for it)
59: * 3) in transit (ip_receiver_name == 0, ip_destination points
60: * to the destination port and holds a ref for it)
61: * 4) in limbo (ip_receiver_name == 0, ip_destination == IP_NULL)
62: *
63: * If the port is active, and ip_receiver points to some space,
64: * then ip_receiver_name != 0, and that space holds receive rights.
65: * If the port is not active, then ip_timestamp contains a timestamp
66: * taken when the port was destroyed.
67: */
68:
69: typedef unsigned int ipc_port_timestamp_t;
70:
71: struct ipc_port {
72: struct ipc_target ip_target;
73:
74: /* This points to the ip_target above if this port isn't on a port set;
75: otherwise it points to the port set's ips_target. */
76: struct ipc_target *ip_cur_target;
77:
78: union {
79: struct ipc_space *receiver;
80: struct ipc_port *destination;
81: ipc_port_timestamp_t timestamp;
82: } data;
83:
84: ipc_kobject_t ip_kobject;
85:
86: mach_port_mscount_t ip_mscount;
87: mach_port_rights_t ip_srights;
88: mach_port_rights_t ip_sorights;
89:
90: struct ipc_port *ip_nsrequest;
91: struct ipc_port *ip_pdrequest;
92: struct ipc_port_request *ip_dnrequests;
93:
94: struct ipc_pset *ip_pset;
95: mach_port_seqno_t ip_seqno; /* locked by message queue */
96: mach_port_msgcount_t ip_msgcount;
97: mach_port_msgcount_t ip_qlimit;
98: struct ipc_thread_queue ip_blocked;
99: };
100:
101: #define ip_object ip_target.ipt_object
102: #define ip_receiver_name ip_target.ipt_name
103: #define ip_messages ip_target.ipt_messages
104: #define ip_references ip_object.io_references
105: #define ip_bits ip_object.io_bits
106: #define ip_receiver data.receiver
107: #define ip_destination data.destination
108: #define ip_timestamp data.timestamp
109:
110: #define IP_NULL ((ipc_port_t) IO_NULL)
111: #define IP_DEAD ((ipc_port_t) IO_DEAD)
112:
113: #define IP_VALID(port) IO_VALID(&(port)->ip_object)
114:
115: #define ip_active(port) io_active(&(port)->ip_object)
116: #define ip_lock_init(port) io_lock_init(&(port)->ip_object)
117: #define ip_lock(port) io_lock(&(port)->ip_object)
118: #define ip_lock_try(port) io_lock_try(&(port)->ip_object)
119: #define ip_unlock(port) io_unlock(&(port)->ip_object)
120: #define ip_check_unlock(port) io_check_unlock(&(port)->ip_object)
121: #define ip_reference(port) io_reference(&(port)->ip_object)
122: #define ip_release(port) io_release(&(port)->ip_object)
123:
124: #define ip_alloc() ((ipc_port_t) io_alloc(IOT_PORT))
125: #define ip_free(port) io_free(IOT_PORT, &(port)->ip_object)
126:
127: #define ip_kotype(port) io_kotype(&(port)->ip_object)
128:
129: typedef ipc_table_index_t ipc_port_request_index_t;
130:
131: typedef struct ipc_port_request {
132: union {
133: struct ipc_port *port;
134: ipc_port_request_index_t index;
135: } notify;
136:
137: union {
138: mach_port_t name;
139: struct ipc_table_size *size;
140: } name;
141: } *ipc_port_request_t;
142:
143: #define ipr_next notify.index
144: #define ipr_size name.size
145:
146: #define ipr_soright notify.port
147: #define ipr_name name.name
148:
149: #define IPR_NULL ((ipc_port_request_t) 0)
150:
151: /*
152: * Taking the ipc_port_multiple lock grants the privilege
153: * to lock multiple ports at once. No ports must locked
154: * when it is taken.
155: */
156:
157: decl_simple_lock_data(extern, ipc_port_multiple_lock_data)
158:
159: #define ipc_port_multiple_lock_init() \
160: simple_lock_init(&ipc_port_multiple_lock_data)
161:
162: #define ipc_port_multiple_lock() \
163: simple_lock(&ipc_port_multiple_lock_data)
164:
165: #define ipc_port_multiple_unlock() \
166: simple_unlock(&ipc_port_multiple_lock_data)
167:
168: /*
169: * The port timestamp facility provides timestamps
170: * for port destruction. It is used to serialize
171: * mach_port_names with port death.
172: */
173:
174: decl_simple_lock_data(extern, ipc_port_timestamp_lock_data)
175: extern ipc_port_timestamp_t ipc_port_timestamp_data;
176:
177: #define ipc_port_timestamp_lock_init() \
178: simple_lock_init(&ipc_port_timestamp_lock_data)
179:
180: #define ipc_port_timestamp_lock() \
181: simple_lock(&ipc_port_timestamp_lock_data)
182:
183: #define ipc_port_timestamp_unlock() \
184: simple_unlock(&ipc_port_timestamp_lock_data)
185:
186: extern ipc_port_timestamp_t
1.1.1.3 ! root 187: ipc_port_timestamp(void);
1.1 root 188:
189: /*
190: * Compares two timestamps, and returns TRUE if one
191: * happened before two. Note that this formulation
192: * works when the timestamp wraps around at 2^32,
193: * as long as one and two aren't too far apart.
194: */
195:
196: #define IP_TIMESTAMP_ORDER(one, two) ((int) ((one) - (two)) < 0)
197:
198: #define ipc_port_translate_receive(space, name, portp) \
199: ipc_object_translate((space), (name), \
200: MACH_PORT_RIGHT_RECEIVE, \
201: (ipc_object_t *) (portp))
202:
203: #define ipc_port_translate_send(space, name, portp) \
204: ipc_object_translate((space), (name), \
205: MACH_PORT_RIGHT_SEND, \
206: (ipc_object_t *) (portp))
207:
208: extern kern_return_t
1.1.1.3 ! root 209: ipc_port_dnrequest(ipc_port_t, mach_port_t, ipc_port_t,
! 210: ipc_port_request_index_t *);
1.1 root 211:
212: extern kern_return_t
1.1.1.3 ! root 213: ipc_port_dngrow(ipc_port_t);
1.1 root 214:
215: extern ipc_port_t
1.1.1.3 ! root 216: ipc_port_dncancel(ipc_port_t, mach_port_t, ipc_port_request_index_t);
1.1 root 217:
218: #define ipc_port_dnrename(port, index, oname, nname) \
219: MACRO_BEGIN \
220: ipc_port_request_t ipr, table; \
221: \
222: assert(ip_active(port)); \
223: \
224: table = port->ip_dnrequests; \
225: assert(table != IPR_NULL); \
226: \
227: ipr = &table[index]; \
228: assert(ipr->ipr_name == oname); \
229: \
230: ipr->ipr_name = nname; \
231: MACRO_END
232:
233: /* Make a port-deleted request */
234: extern void ipc_port_pdrequest(
235: ipc_port_t port,
236: ipc_port_t notify,
237: ipc_port_t *previousp);
238:
239: /* Make a no-senders request */
240: extern void ipc_port_nsrequest(
241: ipc_port_t port,
242: mach_port_mscount_t sync,
243: ipc_port_t notify,
244: ipc_port_t *previousp);
245:
246: /* Change a port's queue limit */
247: extern void ipc_port_set_qlimit(
248: ipc_port_t port,
249: mach_port_msgcount_t qlimit);
250:
251: #define ipc_port_set_mscount(port, mscount) \
252: MACRO_BEGIN \
253: assert(ip_active(port)); \
254: \
255: (port)->ip_mscount = (mscount); \
256: MACRO_END
257:
258: extern struct ipc_mqueue *
1.1.1.3 ! root 259: ipc_port_lock_mqueue(ipc_port_t);
1.1 root 260:
261: extern void
1.1.1.3 ! root 262: ipc_port_set_seqno(ipc_port_t, mach_port_seqno_t);
1.1 root 263:
264: extern void
1.1.1.3 ! root 265: ipc_port_clear_receiver(ipc_port_t);
1.1 root 266:
267: extern void
1.1.1.3 ! root 268: ipc_port_init(ipc_port_t, ipc_space_t, mach_port_t);
1.1 root 269:
270: extern kern_return_t
1.1.1.3 ! root 271: ipc_port_alloc(ipc_space_t, mach_port_t *, ipc_port_t *);
1.1 root 272:
273: extern kern_return_t
1.1.1.3 ! root 274: ipc_port_alloc_name(ipc_space_t, mach_port_t, ipc_port_t *);
1.1 root 275:
276: extern void
1.1.1.3 ! root 277: ipc_port_destroy(ipc_port_t);
1.1 root 278:
279: extern boolean_t
1.1.1.3 ! root 280: ipc_port_check_circularity(ipc_port_t, ipc_port_t);
1.1 root 281:
282: extern ipc_port_t
1.1.1.3 ! root 283: ipc_port_lookup_notify(ipc_space_t, mach_port_t);
1.1 root 284:
285: extern ipc_port_t
1.1.1.3 ! root 286: ipc_port_make_send(ipc_port_t);
1.1 root 287:
288: extern ipc_port_t
1.1.1.3 ! root 289: ipc_port_copy_send(ipc_port_t);
1.1 root 290:
291: extern mach_port_t
1.1.1.3 ! root 292: ipc_port_copyout_send(ipc_port_t, ipc_space_t);
1.1 root 293:
294: extern void
1.1.1.3 ! root 295: ipc_port_release_send(ipc_port_t);
1.1 root 296:
297: extern ipc_port_t
1.1.1.3 ! root 298: ipc_port_make_sonce(ipc_port_t);
1.1 root 299:
300: extern void
1.1.1.3 ! root 301: ipc_port_release_sonce(ipc_port_t);
1.1 root 302:
303: extern void
1.1.1.3 ! root 304: ipc_port_release_receive(ipc_port_t);
1.1 root 305:
306: extern ipc_port_t
1.1.1.3 ! root 307: ipc_port_alloc_special(ipc_space_t);
1.1 root 308:
309: extern void
1.1.1.3 ! root 310: ipc_port_dealloc_special(ipc_port_t, ipc_space_t);
1.1 root 311:
312: #define ipc_port_alloc_kernel() \
313: ipc_port_alloc_special(ipc_space_kernel)
314: #define ipc_port_dealloc_kernel(port) \
315: ipc_port_dealloc_special((port), ipc_space_kernel)
316:
317: #define ipc_port_alloc_reply() \
318: ipc_port_alloc_special(ipc_space_reply)
319: #define ipc_port_dealloc_reply(port) \
320: ipc_port_dealloc_special((port), ipc_space_reply)
321:
322: #define ipc_port_reference(port) \
323: ipc_object_reference(&(port)->ip_object)
324:
325: #define ipc_port_release(port) \
326: ipc_object_release(&(port)->ip_object)
327:
1.1.1.2 root 328: #endif /* _IPC_IPC_PORT_H_ */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.