Annotation of kernel/ipc/ipc_port.h, revision 1.1.1.1

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_ */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.