|
|
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_ipc_compat.h> ! 43: #include <norma_ipc.h> ! 44: ! 45: #include <mach/boolean.h> ! 46: #include <mach/kern_return.h> ! 47: #include <mach/port.h> ! 48: #include <kern/lock.h> ! 49: #include <kern/macro_help.h> ! 50: #include <kern/ipc_kobject.h> ! 51: #include <ipc/ipc_mqueue.h> ! 52: #include <ipc/ipc_table.h> ! 53: #include <ipc/ipc_thread.h> ! 54: #include "ipc_target.h" ! 55: #include <mach/rpc.h> ! 56: ! 57: /* ! 58: * A receive right (port) can be in four states: ! 59: * 1) dead (not active, ip_timestamp has death time) ! 60: * 2) in a space (ip_receiver_name != 0, ip_receiver points ! 61: * to the space but doesn't hold a ref for it) ! 62: * 3) in transit (ip_receiver_name == 0, ip_destination points ! 63: * to the destination port and holds a ref for it) ! 64: * 4) in limbo (ip_receiver_name == 0, ip_destination == IP_NULL) ! 65: * ! 66: * If the port is active, and ip_receiver points to some space, ! 67: * then ip_receiver_name != 0, and that space holds receive rights. ! 68: * If the port is not active, then ip_timestamp contains a timestamp ! 69: * taken when the port was destroyed. ! 70: */ ! 71: ! 72: typedef unsigned int ipc_port_timestamp_t; ! 73: ! 74: struct ipc_port { ! 75: struct ipc_target ip_target; ! 76: ! 77: /* This points to the ip_target above if this port isn't on a port set; ! 78: otherwise it points to the port set's ips_target. */ ! 79: struct ipc_target *ip_cur_target; ! 80: ! 81: union { ! 82: struct ipc_space *receiver; ! 83: struct ipc_port *destination; ! 84: ipc_port_timestamp_t timestamp; ! 85: } data; ! 86: ! 87: ipc_kobject_t ip_kobject; ! 88: ! 89: mach_port_mscount_t ip_mscount; ! 90: mach_port_rights_t ip_srights; ! 91: mach_port_rights_t ip_sorights; ! 92: ! 93: struct ipc_port *ip_nsrequest; ! 94: struct ipc_port *ip_pdrequest; ! 95: struct ipc_port_request *ip_dnrequests; ! 96: ! 97: struct ipc_pset *ip_pset; ! 98: mach_port_seqno_t ip_seqno; /* locked by message queue */ ! 99: mach_port_msgcount_t ip_msgcount; ! 100: mach_port_msgcount_t ip_qlimit; ! 101: struct ipc_thread_queue ip_blocked; ! 102: ! 103: #if NORMA_IPC ! 104: unsigned long ip_norma_uid; ! 105: unsigned long ip_norma_dest_node; ! 106: long ip_norma_stransit; ! 107: long ip_norma_sotransit; ! 108: long ip_norma_xmm_object_refs; ! 109: boolean_t ip_norma_is_proxy; ! 110: boolean_t ip_norma_is_special; ! 111: struct ipc_port *ip_norma_atrium; ! 112: struct ipc_port *ip_norma_queue_next; ! 113: struct ipc_port *ip_norma_xmm_object; ! 114: struct ipc_port *ip_norma_next; ! 115: long ip_norma_spare1; ! 116: long ip_norma_spare2; ! 117: long ip_norma_spare3; ! 118: long ip_norma_spare4; ! 119: #endif NORMA_IPC ! 120: }; ! 121: ! 122: #define ip_object ip_target.ipt_object ! 123: #define ip_receiver_name ip_target.ipt_name ! 124: #define ip_messages ip_target.ipt_messages ! 125: #define ip_references ip_object.io_references ! 126: #define ip_bits ip_object.io_bits ! 127: #define ip_receiver data.receiver ! 128: #define ip_destination data.destination ! 129: #define ip_timestamp data.timestamp ! 130: ! 131: #define IP_NULL ((ipc_port_t) IO_NULL) ! 132: #define IP_DEAD ((ipc_port_t) IO_DEAD) ! 133: ! 134: #define IP_VALID(port) IO_VALID(&(port)->ip_object) ! 135: ! 136: #define ip_active(port) io_active(&(port)->ip_object) ! 137: #define ip_lock_init(port) io_lock_init(&(port)->ip_object) ! 138: #define ip_lock(port) io_lock(&(port)->ip_object) ! 139: #define ip_lock_try(port) io_lock_try(&(port)->ip_object) ! 140: #define ip_unlock(port) io_unlock(&(port)->ip_object) ! 141: #define ip_check_unlock(port) io_check_unlock(&(port)->ip_object) ! 142: #define ip_reference(port) io_reference(&(port)->ip_object) ! 143: #define ip_release(port) io_release(&(port)->ip_object) ! 144: ! 145: #define ip_alloc() ((ipc_port_t) io_alloc(IOT_PORT)) ! 146: #define ip_free(port) io_free(IOT_PORT, &(port)->ip_object) ! 147: ! 148: #define ip_kotype(port) io_kotype(&(port)->ip_object) ! 149: ! 150: typedef ipc_table_index_t ipc_port_request_index_t; ! 151: ! 152: typedef struct ipc_port_request { ! 153: union { ! 154: struct ipc_port *port; ! 155: ipc_port_request_index_t index; ! 156: } notify; ! 157: ! 158: union { ! 159: mach_port_t name; ! 160: struct ipc_table_size *size; ! 161: } name; ! 162: } *ipc_port_request_t; ! 163: ! 164: #define ipr_next notify.index ! 165: #define ipr_size name.size ! 166: ! 167: #define ipr_soright notify.port ! 168: #define ipr_name name.name ! 169: ! 170: #define IPR_NULL ((ipc_port_request_t) 0) ! 171: ! 172: #if MACH_IPC_COMPAT ! 173: /* ! 174: * For backwards compatibility, the ip_pdrequest field can hold a ! 175: * send right instead of a send-once right. This is indicated by ! 176: * the low bit of the pointer. This works because the zone package ! 177: * guarantees that the two low bits of port pointers are zero. ! 178: */ ! 179: ! 180: #define ip_pdsendp(soright) ((unsigned int)(soright) & 1) ! 181: #define ip_pdsend(soright) ((ipc_port_t)((unsigned int)(soright) &~ 1)) ! 182: #define ip_pdsendm(sright) ((ipc_port_t)((unsigned int)(sright) | 1)) ! 183: ! 184: /* ! 185: * For backwards compatibility, the ipr_soright field can hold ! 186: * a space pointer. This is indicated by the low bit of the pointer. ! 187: * This works because the zone package guarantees that the two low ! 188: * bits of port and space pointers are zero. ! 189: */ ! 190: ! 191: #define ipr_spacep(soright) ((unsigned int)(soright) & 1) ! 192: #define ipr_space(soright) ((ipc_space_t)((unsigned int)(soright) &~ 1)) ! 193: #define ipr_spacem(space) ((ipc_port_t)((unsigned int)(space) | 1)) ! 194: #endif MACH_IPC_COMPAT ! 195: ! 196: /* ! 197: * Taking the ipc_port_multiple lock grants the privilege ! 198: * to lock multiple ports at once. No ports must locked ! 199: * when it is taken. ! 200: */ ! 201: ! 202: decl_simple_lock_data(extern, ipc_port_multiple_lock_data) ! 203: ! 204: #define ipc_port_multiple_lock_init() \ ! 205: simple_lock_init(&ipc_port_multiple_lock_data) ! 206: ! 207: #define ipc_port_multiple_lock() \ ! 208: simple_lock(&ipc_port_multiple_lock_data) ! 209: ! 210: #define ipc_port_multiple_unlock() \ ! 211: simple_unlock(&ipc_port_multiple_lock_data) ! 212: ! 213: /* ! 214: * The port timestamp facility provides timestamps ! 215: * for port destruction. It is used to serialize ! 216: * mach_port_names with port death. ! 217: */ ! 218: ! 219: decl_simple_lock_data(extern, ipc_port_timestamp_lock_data) ! 220: extern ipc_port_timestamp_t ipc_port_timestamp_data; ! 221: ! 222: #define ipc_port_timestamp_lock_init() \ ! 223: simple_lock_init(&ipc_port_timestamp_lock_data) ! 224: ! 225: #define ipc_port_timestamp_lock() \ ! 226: simple_lock(&ipc_port_timestamp_lock_data) ! 227: ! 228: #define ipc_port_timestamp_unlock() \ ! 229: simple_unlock(&ipc_port_timestamp_lock_data) ! 230: ! 231: extern ipc_port_timestamp_t ! 232: ipc_port_timestamp(); ! 233: ! 234: /* ! 235: * Compares two timestamps, and returns TRUE if one ! 236: * happened before two. Note that this formulation ! 237: * works when the timestamp wraps around at 2^32, ! 238: * as long as one and two aren't too far apart. ! 239: */ ! 240: ! 241: #define IP_TIMESTAMP_ORDER(one, two) ((int) ((one) - (two)) < 0) ! 242: ! 243: #define ipc_port_translate_receive(space, name, portp) \ ! 244: ipc_object_translate((space), (name), \ ! 245: MACH_PORT_RIGHT_RECEIVE, \ ! 246: (ipc_object_t *) (portp)) ! 247: ! 248: #define ipc_port_translate_send(space, name, portp) \ ! 249: ipc_object_translate((space), (name), \ ! 250: MACH_PORT_RIGHT_SEND, \ ! 251: (ipc_object_t *) (portp)) ! 252: ! 253: extern kern_return_t ! 254: ipc_port_dnrequest(/* ipc_port_t, mach_port_t, ipc_port_t, ! 255: ipc_port_request_index_t * */); ! 256: ! 257: extern kern_return_t ! 258: ipc_port_dngrow(/* ipc_port_t */); ! 259: ! 260: extern ipc_port_t ! 261: ipc_port_dncancel(/* ipc_port_t, mach_port_t, ipc_port_request_index_t */); ! 262: ! 263: #define ipc_port_dnrename(port, index, oname, nname) \ ! 264: MACRO_BEGIN \ ! 265: ipc_port_request_t ipr, table; \ ! 266: \ ! 267: assert(ip_active(port)); \ ! 268: \ ! 269: table = port->ip_dnrequests; \ ! 270: assert(table != IPR_NULL); \ ! 271: \ ! 272: ipr = &table[index]; \ ! 273: assert(ipr->ipr_name == oname); \ ! 274: \ ! 275: ipr->ipr_name = nname; \ ! 276: MACRO_END ! 277: ! 278: /* Make a port-deleted request */ ! 279: extern void ipc_port_pdrequest( ! 280: ipc_port_t port, ! 281: ipc_port_t notify, ! 282: ipc_port_t *previousp); ! 283: ! 284: /* Make a no-senders request */ ! 285: extern void ipc_port_nsrequest( ! 286: ipc_port_t port, ! 287: mach_port_mscount_t sync, ! 288: ipc_port_t notify, ! 289: ipc_port_t *previousp); ! 290: ! 291: /* Change a port's queue limit */ ! 292: extern void ipc_port_set_qlimit( ! 293: ipc_port_t port, ! 294: mach_port_msgcount_t qlimit); ! 295: ! 296: #define ipc_port_set_mscount(port, mscount) \ ! 297: MACRO_BEGIN \ ! 298: assert(ip_active(port)); \ ! 299: \ ! 300: (port)->ip_mscount = (mscount); \ ! 301: MACRO_END ! 302: ! 303: extern struct ipc_mqueue * ! 304: ipc_port_lock_mqueue(/* ipc_port_t */); ! 305: ! 306: extern void ! 307: ipc_port_set_seqno(/* ipc_port_t, mach_port_seqno_t */); ! 308: ! 309: extern void ! 310: ipc_port_clear_receiver(/* ipc_port_t */); ! 311: ! 312: extern void ! 313: ipc_port_init(/* ipc_port_t, ipc_space_t, mach_port_t */); ! 314: ! 315: extern kern_return_t ! 316: ipc_port_alloc(/* ipc_space_t, mach_port_t *, ipc_port_t * */); ! 317: ! 318: extern kern_return_t ! 319: ipc_port_alloc_name(/* ipc_space_t, mach_port_t, ipc_port_t * */); ! 320: ! 321: extern void ! 322: ipc_port_destroy(/* ipc_port_t */); ! 323: ! 324: extern boolean_t ! 325: ipc_port_check_circularity(/* ipc_port_t, ipc_port_t */); ! 326: ! 327: extern ipc_port_t ! 328: ipc_port_lookup_notify(/* ipc_space_t, mach_port_t */); ! 329: ! 330: extern ipc_port_t ! 331: ipc_port_make_send(/* ipc_port_t */); ! 332: ! 333: extern ipc_port_t ! 334: ipc_port_copy_send(/* ipc_port_t */); ! 335: ! 336: extern mach_port_t ! 337: ipc_port_copyout_send(/* ipc_port_t, ipc_space_t */); ! 338: ! 339: extern void ! 340: ipc_port_release_send(/* ipc_port_t */); ! 341: ! 342: extern ipc_port_t ! 343: ipc_port_make_sonce(/* ipc_port_t */); ! 344: ! 345: extern void ! 346: ipc_port_release_sonce(/* ipc_port_t */); ! 347: ! 348: extern void ! 349: ipc_port_release_receive(/* ipc_port_t */); ! 350: ! 351: extern ipc_port_t ! 352: ipc_port_alloc_special(/* ipc_space_t */); ! 353: ! 354: extern void ! 355: ipc_port_dealloc_special(/* ipc_port_t */); ! 356: ! 357: #define ipc_port_alloc_kernel() \ ! 358: ipc_port_alloc_special(ipc_space_kernel) ! 359: #define ipc_port_dealloc_kernel(port) \ ! 360: ipc_port_dealloc_special((port), ipc_space_kernel) ! 361: ! 362: #define ipc_port_alloc_reply() \ ! 363: ipc_port_alloc_special(ipc_space_reply) ! 364: #define ipc_port_dealloc_reply(port) \ ! 365: ipc_port_dealloc_special((port), ipc_space_reply) ! 366: ! 367: #define ipc_port_reference(port) \ ! 368: ipc_object_reference(&(port)->ip_object) ! 369: ! 370: #define ipc_port_release(port) \ ! 371: ipc_object_release(&(port)->ip_object) ! 372: ! 373: #if MACH_IPC_COMPAT ! 374: ! 375: extern kern_return_t ! 376: ipc_port_alloc_compat(/* ipc_space_t, mach_port_t *, ipc_port_t * */); ! 377: ! 378: extern mach_port_t ! 379: ipc_port_copyout_send_compat(/* ipc_port_t, ipc_space_t */); ! 380: ! 381: extern mach_port_t ! 382: ipc_port_copyout_receiver(/* ipc_port_t, ipc_space_t */); ! 383: ! 384: #endif MACH_IPC_COMPAT ! 385: ! 386: extern void ! 387: ipc_port_print(/* ipc_port_t */); ! 388: ! 389: #if NORMA_IPC ! 390: ! 391: #define IP_NORMA_IS_PROXY(port) ((port)->ip_norma_is_proxy) ! 392: ! 393: /* ! 394: * A proxy never has a real nsrequest, but is always has a fake ! 395: * nsrequest so that the norma ipc system is notified when there ! 396: * are no send rights for a proxy. A fake nsrequest is indicated by ! 397: * the low bit of the pointer. This works because the zone package ! 398: * guarantees that the two low bits of port pointers are zero. ! 399: */ ! 400: ! 401: #define ip_nsproxyp(nsrequest) ((unsigned int)(nsrequest) & 1) ! 402: #define ip_nsproxy(nsrequest) ((ipc_port_t)((unsigned int)(nsrequest) &~ 1)) ! 403: #define ip_nsproxym(proxy) ((ipc_port_t)((unsigned int)(proxy) | 1)) ! 404: ! 405: #endif NORMA_IPC ! 406: ! 407: #endif _IPC_IPC_PORT_H_
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.