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