|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * The contents of this file constitute Original Code as defined in and ! 7: * are subject to the Apple Public Source License Version 1.1 (the ! 8: * "License"). You may not use this file except in compliance with the ! 9: * License. Please obtain a copy of the License at ! 10: * http://www.apple.com/publicsource and read it before using this file. ! 11: * ! 12: * This Original Code and all software distributed under the License are ! 13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 17: * License for the specific language governing rights and limitations ! 18: * under the License. ! 19: * ! 20: * @APPLE_LICENSE_HEADER_END@ ! 21: */ ! 22: /* ! 23: * @OSF_COPYRIGHT@ ! 24: */ ! 25: /* ! 26: * Mach Operating System ! 27: * Copyright (c) 1991,1990,1989 Carnegie Mellon University ! 28: * All Rights Reserved. ! 29: * ! 30: * Permission to use, copy, modify and distribute this software and its ! 31: * documentation is hereby granted, provided that both the copyright ! 32: * notice and this permission notice appear in all copies of the ! 33: * software, derivative works or modified versions, and any portions ! 34: * thereof, and that both notices appear in supporting documentation. ! 35: * ! 36: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" ! 37: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR ! 38: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. ! 39: * ! 40: * Carnegie Mellon requests users of this software to return to ! 41: * ! 42: * Software Distribution Coordinator or [email protected] ! 43: * School of Computer Science ! 44: * Carnegie Mellon University ! 45: * Pittsburgh PA 15213-3890 ! 46: * ! 47: * any improvements or extensions that they make and grant Carnegie Mellon ! 48: * the rights to redistribute these changes. ! 49: */ ! 50: /* ! 51: */ ! 52: /* ! 53: * File: ipc/ipc_port.h ! 54: * Author: Rich Draves ! 55: * Date: 1989 ! 56: * ! 57: * Definitions for ports. ! 58: */ ! 59: ! 60: #ifndef _IPC_IPC_PORT_H_ ! 61: #define _IPC_IPC_PORT_H_ ! 62: ! 63: #include <dipc.h> ! 64: #include <norma_vm.h> ! 65: #include <mach_rt.h> ! 66: #include <mach_assert.h> ! 67: #include <mach_debug.h> ! 68: ! 69: #include <mach/boolean.h> ! 70: #include <mach/kern_return.h> ! 71: #include <mach_debug.h> ! 72: #include <mach/port.h> ! 73: #include <kern/lock.h> ! 74: #include <kern/ipc_kobject.h> ! 75: #include <kern/wait_queue.h> ! 76: #include <kern/thread_pool.h> ! 77: ! 78: #include <ipc/ipc_object.h> ! 79: #include <ipc/ipc_mqueue.h> ! 80: #include <ipc/ipc_table.h> ! 81: #include <ipc/ipc_types.h> ! 82: #include <ipc/ipc_entry.h> ! 83: ! 84: /* ! 85: * A receive right (port) can be in four states: ! 86: * 1) dead (not active, ip_timestamp has death time) ! 87: * 2) in a space (ip_receiver_name != 0, ip_receiver points ! 88: * to the space but doesn't hold a ref for it) ! 89: * 3) in transit (ip_receiver_name == 0, ip_destination points ! 90: * to the destination port and holds a ref for it) ! 91: * 4) in limbo (ip_receiver_name == 0, ip_destination == IP_NULL) ! 92: * ! 93: * If the port is active, and ip_receiver points to some space, ! 94: * then ip_receiver_name != 0, and that space holds receive rights. ! 95: * If the port is not active, then ip_timestamp contains a timestamp ! 96: * taken when the port was destroyed. ! 97: */ ! 98: ! 99: typedef unsigned int ipc_port_timestamp_t; ! 100: ! 101: typedef unsigned int ipc_port_flags_t; ! 102: ! 103: struct ipc_port { ! 104: ! 105: /* ! 106: * Initial sub-structure in common with ipc_pset and rpc_port ! 107: * First element is an ipc_object ! 108: */ ! 109: struct ipc_object ip_object; ! 110: ! 111: union { ! 112: struct ipc_space *receiver; ! 113: struct ipc_port *destination; ! 114: ipc_port_timestamp_t timestamp; ! 115: } data; ! 116: ! 117: ipc_kobject_t ip_kobject; ! 118: struct rpc_subsystem * ip_subsystem; ! 119: mach_port_mscount_t ip_mscount; ! 120: mach_port_rights_t ip_srights; ! 121: mach_port_rights_t ip_sorights; ! 122: ! 123: struct ipc_port *ip_nsrequest; ! 124: struct ipc_port *ip_pdrequest; ! 125: struct ipc_port_request *ip_dnrequests; ! 126: ! 127: unsigned int ip_pset_count; ! 128: struct ipc_mqueue ip_messages; ! 129: ipc_port_flags_t ip_flags; ! 130: ! 131: #if NORMA_VM ! 132: /* ! 133: * These fields are needed for the use of XMM. ! 134: * Few ports need this information; it should ! 135: * be kept in XMM instead (TBD). XXX ! 136: */ ! 137: long ip_norma_xmm_object_refs; ! 138: struct ipc_port *ip_norma_xmm_object; ! 139: #endif ! 140: ! 141: #if MACH_ASSERT ! 142: #define IP_NSPARES 10 ! 143: #define IP_CALLSTACK_MAX 10 ! 144: queue_chain_t ip_port_links; /* all allocated ports */ ! 145: natural_t ip_thread; /* who made me? thread context */ ! 146: unsigned long ip_timetrack; /* give an idea of "when" created */ ! 147: natural_t ip_callstack[IP_CALLSTACK_MAX]; /* stack trace */ ! 148: unsigned long ip_spares[IP_NSPARES]; /* for debugging */ ! 149: #endif /* MACH_ASSERT */ ! 150: int alias; ! 151: }; ! 152: ! 153: ! 154: #define ip_references ip_object.io_references ! 155: #define ip_bits ip_object.io_bits ! 156: #define ip_receiver_name ip_object.io_receiver_name ! 157: ! 158: #define ip_thread_pool ip_object.io_thread_pool ! 159: ! 160: #define ip_receiver data.receiver ! 161: #define ip_destination data.destination ! 162: #define ip_timestamp data.timestamp ! 163: ! 164: #define IP_NULL IPC_PORT_NULL ! 165: #define IP_DEAD IPC_PORT_DEAD ! 166: #define IP_VALID(port) IPC_PORT_VALID(port) ! 167: ! 168: #define ip_active(port) io_active(&(port)->ip_object) ! 169: #define ip_lock_init(port) io_lock_init(&(port)->ip_object) ! 170: #define ip_lock(port) io_lock(&(port)->ip_object) ! 171: #define ip_lock_try(port) io_lock_try(&(port)->ip_object) ! 172: #define ip_unlock(port) io_unlock(&(port)->ip_object) ! 173: #define ip_check_unlock(port) io_check_unlock(&(port)->ip_object) ! 174: ! 175: #define ip_reference(port) io_reference(&(port)->ip_object) ! 176: #define ip_release(port) io_release(&(port)->ip_object) ! 177: ! 178: #define ip_kotype(port) io_kotype(&(port)->ip_object) ! 179: ! 180: #if MACH_RT ! 181: #define IPC_PORT_FLAGS_RT ((ipc_port_flags_t)(1 << 0)) ! 182: #define IP_RT(port) (((port)->ip_flags & IPC_PORT_FLAGS_RT) != 0) ! 183: #else /* MACH_RT */ ! 184: #define IP_RT(port) (0) ! 185: #endif /* MACH_RT */ ! 186: ! 187: /* ! 188: * No more senders information. ! 189: */ ! 190: #define IP_BIT_NMS 0x00008000 /* nms detection enabled? */ ! 191: #define IP_SET_NMS(port) ((port)->ip_bits |= IP_BIT_NMS) ! 192: #define IP_CLEAR_NMS(port) ((port)->ip_bits &= ~IP_BIT_NMS) ! 193: #define IP_NMS(port) ((port)->ip_bits & IP_BIT_NMS) ! 194: ! 195: typedef ipc_table_index_t ipc_port_request_index_t; ! 196: ! 197: typedef struct ipc_port_request { ! 198: union { ! 199: struct ipc_port *port; ! 200: ipc_port_request_index_t index; ! 201: } notify; ! 202: ! 203: union { ! 204: mach_port_name_t name; ! 205: struct ipc_table_size *size; ! 206: } name; ! 207: } *ipc_port_request_t; ! 208: ! 209: #define ipr_next notify.index ! 210: #define ipr_size name.size ! 211: ! 212: #define ipr_soright notify.port ! 213: #define ipr_name name.name ! 214: ! 215: #define IPR_NULL ((ipc_port_request_t) 0) ! 216: ! 217: /* ! 218: * Taking the ipc_port_multiple lock grants the privilege ! 219: * to lock multiple ports at once. No ports must locked ! 220: * when it is taken. ! 221: */ ! 222: ! 223: decl_mutex_data(extern,ipc_port_multiple_lock_data) ! 224: ! 225: #define ipc_port_multiple_lock_init() \ ! 226: mutex_init(&ipc_port_multiple_lock_data, ETAP_IPC_PORT_MULT) ! 227: ! 228: #define ipc_port_multiple_lock() \ ! 229: mutex_lock(&ipc_port_multiple_lock_data) ! 230: ! 231: #define ipc_port_multiple_unlock() \ ! 232: mutex_unlock(&ipc_port_multiple_lock_data) ! 233: ! 234: /* ! 235: * The port timestamp facility provides timestamps ! 236: * for port destruction. It is used to serialize ! 237: * mach_port_names with port death. ! 238: */ ! 239: ! 240: decl_mutex_data(extern,ipc_port_timestamp_lock_data) ! 241: extern ipc_port_timestamp_t ipc_port_timestamp_data; ! 242: ! 243: #define ipc_port_timestamp_lock_init() \ ! 244: mutex_init(&ipc_port_timestamp_lock_data, ETAP_IPC_PORT_TIME) ! 245: ! 246: #define ipc_port_timestamp_lock() \ ! 247: mutex_lock(&ipc_port_timestamp_lock_data) ! 248: ! 249: #define ipc_port_timestamp_unlock() \ ! 250: mutex_unlock(&ipc_port_timestamp_lock_data) ! 251: ! 252: /* Retrieve a port timestamp value */ ! 253: extern ipc_port_timestamp_t ipc_port_timestamp(void); ! 254: ! 255: /* ! 256: * Compares two timestamps, and returns TRUE if one ! 257: * happened before two. Note that this formulation ! 258: * works when the timestamp wraps around at 2^32, ! 259: * as long as one and two aren't too far apart. ! 260: */ ! 261: ! 262: #define IP_TIMESTAMP_ORDER(one, two) ((int) ((one) - (two)) < 0) ! 263: ! 264: #define ipc_port_translate_receive(space, name, portp) \ ! 265: ipc_object_translate((space), (name), \ ! 266: MACH_PORT_RIGHT_RECEIVE, \ ! 267: (ipc_object_t *) (portp)) ! 268: ! 269: #define ipc_port_translate_send(space, name, portp) \ ! 270: ipc_object_translate((space), (name), \ ! 271: MACH_PORT_RIGHT_SEND, \ ! 272: (ipc_object_t *) (portp)) ! 273: ! 274: /* Allocate a dead-name request slot */ ! 275: extern kern_return_t ! 276: ipc_port_dnrequest( ! 277: ipc_port_t port, ! 278: mach_port_name_t name, ! 279: ipc_port_t soright, ! 280: ipc_port_request_index_t *indexp); ! 281: ! 282: /* Grow a port's table of dead-name requests */ ! 283: extern kern_return_t ipc_port_dngrow( ! 284: ipc_port_t port, ! 285: int target_size); ! 286: ! 287: /* Cancel a dead-name request and return the send-once right */ ! 288: extern ipc_port_t ipc_port_dncancel( ! 289: ipc_port_t port, ! 290: mach_port_name_t name, ! 291: ipc_port_request_index_t index); ! 292: ! 293: #define ipc_port_dnrename(port, index, oname, nname) \ ! 294: MACRO_BEGIN \ ! 295: ipc_port_request_t ipr, table; \ ! 296: \ ! 297: assert(ip_active(port)); \ ! 298: \ ! 299: table = port->ip_dnrequests; \ ! 300: assert(table != IPR_NULL); \ ! 301: \ ! 302: ipr = &table[index]; \ ! 303: assert(ipr->ipr_name == oname); \ ! 304: \ ! 305: ipr->ipr_name = nname; \ ! 306: MACRO_END ! 307: ! 308: /* Make a port-deleted request */ ! 309: extern void ipc_port_pdrequest( ! 310: ipc_port_t port, ! 311: ipc_port_t notify, ! 312: ipc_port_t *previousp); ! 313: ! 314: /* Make a no-senders request */ ! 315: extern void ipc_port_nsrequest( ! 316: ipc_port_t port, ! 317: mach_port_mscount_t sync, ! 318: ipc_port_t notify, ! 319: ipc_port_t *previousp); ! 320: ! 321: #define ipc_port_set_mscount(port, mscount) \ ! 322: MACRO_BEGIN \ ! 323: assert(ip_active(port)); \ ! 324: \ ! 325: (port)->ip_mscount = (mscount); \ ! 326: MACRO_END ! 327: ! 328: /* Prepare a receive right for transmission/destruction */ ! 329: extern void ipc_port_clear_receiver( ! 330: ipc_port_t port); ! 331: ! 332: /* Initialize a newly-allocated port */ ! 333: extern void ipc_port_init( ! 334: ipc_port_t port, ! 335: ipc_space_t space, ! 336: mach_port_name_t name); ! 337: ! 338: /* Allocate a port */ ! 339: extern kern_return_t ipc_port_alloc( ! 340: ipc_space_t space, ! 341: mach_port_name_t *namep, ! 342: ipc_port_t *portp); ! 343: ! 344: /* Allocate a port, with a specific name */ ! 345: extern kern_return_t ipc_port_alloc_name( ! 346: ipc_space_t space, ! 347: mach_port_name_t name, ! 348: ipc_port_t *portp); ! 349: ! 350: /* Generate dead name notifications */ ! 351: extern void ipc_port_dnnotify( ! 352: ipc_port_t port, ! 353: ipc_port_request_t dnrequests); ! 354: ! 355: /* Destroy a port */ ! 356: extern void ipc_port_destroy( ! 357: ipc_port_t port); ! 358: ! 359: /* Check if queueing "port" in a message for "dest" would create a circular ! 360: group of ports and messages */ ! 361: extern boolean_t ! 362: ipc_port_check_circularity( ! 363: ipc_port_t port, ! 364: ipc_port_t dest); ! 365: ! 366: /* Make a send-once notify port from a receive right */ ! 367: extern ipc_port_t ipc_port_lookup_notify( ! 368: ipc_space_t space, ! 369: mach_port_name_t name); ! 370: ! 371: /* Make a naked send right from a receive right */ ! 372: extern ipc_port_t ipc_port_make_send( ! 373: ipc_port_t port); ! 374: ! 375: /* Make a naked send right from another naked send right */ ! 376: extern ipc_port_t ipc_port_copy_send( ! 377: ipc_port_t port); ! 378: ! 379: /* Copyout a naked send right */ ! 380: extern mach_port_name_t ipc_port_copyout_send( ! 381: ipc_port_t sright, ! 382: ipc_space_t space); ! 383: ! 384: /* Release a (valid) naked send right */ ! 385: extern void ipc_port_release_send( ! 386: ipc_port_t port); ! 387: ! 388: /* Make a naked send-once right from a receive right */ ! 389: extern ipc_port_t ipc_port_make_sonce( ! 390: ipc_port_t port); ! 391: ! 392: /* Release a naked send-once right */ ! 393: extern void ipc_port_release_sonce( ! 394: ipc_port_t port); ! 395: ! 396: /* Release a naked (in limbo or in transit) receive right */ ! 397: extern void ipc_port_release_receive( ! 398: ipc_port_t port); ! 399: ! 400: /* Allocate a port in a special space */ ! 401: extern ipc_port_t ipc_port_alloc_special( ! 402: ipc_space_t space); ! 403: ! 404: /* Deallocate a port in a special space */ ! 405: extern void ipc_port_dealloc_special( ! 406: ipc_port_t port, ! 407: ipc_space_t space); ! 408: ! 409: #if MACH_ASSERT ! 410: /* Track low-level port deallocation */ ! 411: extern void ipc_port_track_dealloc( ! 412: ipc_port_t port); ! 413: ! 414: /* Initialize general port debugging state */ ! 415: extern void ipc_port_debug_init(void); ! 416: #endif /* MACH_ASSERT */ ! 417: ! 418: #define ipc_port_alloc_kernel() \ ! 419: ipc_port_alloc_special(ipc_space_kernel) ! 420: #define ipc_port_dealloc_kernel(port) \ ! 421: ipc_port_dealloc_special((port), ipc_space_kernel) ! 422: ! 423: #define ipc_port_alloc_reply() \ ! 424: ipc_port_alloc_special(ipc_space_reply) ! 425: #define ipc_port_dealloc_reply(port) \ ! 426: ipc_port_dealloc_special((port), ipc_space_reply) ! 427: ! 428: #define ipc_port_reference(port) \ ! 429: ipc_object_reference(&(port)->ip_object) ! 430: ! 431: #define ipc_port_release(port) \ ! 432: ipc_object_release(&(port)->ip_object) ! 433: ! 434: #endif /* _IPC_IPC_PORT_H_ */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.