Annotation of Gnu-Mach/ipc/ipc_port.h, revision 1.1.1.1

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_

unix.superglobalmegacorp.com

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