Annotation of XNU/osfmk/ipc/ipc_port.h, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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