Annotation of XNU/osfmk/ipc/ipc_object.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_object.h
                     54:  *     Author: Rich Draves
                     55:  *     Date:   1989
                     56:  *
                     57:  *     Definitions for IPC objects, for which tasks have capabilities.
                     58:  */
                     59: 
                     60: #ifndef        _IPC_IPC_OBJECT_H_
                     61: #define _IPC_IPC_OBJECT_H_
                     62: 
                     63: #include <dipc.h>
                     64: #include <mach_rt.h>
                     65: #include <cpus.h>
                     66: #include <mach_kdb.h>
                     67: 
                     68: #include <mach/kern_return.h>
                     69: #include <mach/message.h>
                     70: #include <kern/lock.h>
                     71: #include <kern/macro_help.h>
                     72: #include <kern/thread_pool.h>
                     73: #include <kern/zalloc.h>
                     74: #include <ipc/ipc_types.h>
                     75: 
                     76: typedef natural_t ipc_object_refs_t;   /* for ipc/ipc_object.h         */
                     77: typedef natural_t ipc_object_bits_t;
                     78: typedef natural_t ipc_object_type_t;
                     79: 
                     80: /*
                     81:  * There is no lock in the ipc_object; it is in the enclosing kernel
                     82:  * data structure (rpc_common_data) used by both ipc_port and ipc_pset.
                     83:  * The ipc_object is used to both tag and reference count these two data
                     84:  * structures, and (Noto Bene!) pointers to either of these or the
                     85:  * ipc_object at the head of these are freely cast back and forth; hence
                     86:  * the ipc_object MUST BE FIRST in the ipc_common_data.
                     87:  * 
                     88:  * If the RPC implementation enabled user-mode code to use kernel-level
                     89:  * data structures (as ours used to), this peculiar structuring would
                     90:  * avoid having anything in user code depend on the kernel configuration
                     91:  * (with which lock size varies).
                     92:  */
                     93: struct ipc_object {
                     94:        ipc_object_refs_t io_references;
                     95:        ipc_object_bits_t io_bits;
                     96:        port_name_t       io_receiver_name;
                     97:        struct thread_pool      io_thread_pool;
                     98: #if DIPC && NCPUS == 1
                     99:        usimple_lock_data_t     io_lock_data;
                    100: #else
                    101:        decl_mutex_data(,       io_lock_data)
                    102: #endif
                    103: };
                    104: 
                    105: /*
                    106:  * Legacy defines.  Should use IPC_OBJECT_NULL, etc...
                    107:  */
                    108: #define        IO_NULL                 ((ipc_object_t) 0)
                    109: #define        IO_DEAD                 ((ipc_object_t) -1)
                    110: #define        IO_VALID(io)            (((io) != IO_NULL) && ((io) != IO_DEAD))
                    111: 
                    112: /*
                    113:  *     IPC steals the high-order bits from the kotype to use
                    114:  *     for its own purposes.  This allows IPC to record facts
                    115:  *     about ports that aren't otherwise obvious from the
                    116:  *     existing port fields.  In particular, IPC can optionally
                    117:  *     mark a port for no more senders detection.  Any change
                    118:  *     to IO_BITS_PORT_INFO must be coordinated with bitfield
                    119:  *     definitions in ipc_port.h.
                    120:  */
                    121: #define        IO_BITS_PORT_INFO       0x0000f000      /* stupid port tricks */
                    122: #define        IO_BITS_KOTYPE          0x00000fff      /* used by the object */
                    123: #define IO_BITS_OTYPE          0x7fff0000      /* determines a zone */
                    124: #define        IO_BITS_ACTIVE          0x80000000      /* is object alive? */
                    125: 
                    126: #define        io_active(io)           ((io)->io_bits & IO_BITS_ACTIVE)
                    127: 
                    128: #define        io_otype(io)            (((io)->io_bits & IO_BITS_OTYPE) >> 16)
                    129: #define        io_kotype(io)           ((io)->io_bits & IO_BITS_KOTYPE)
                    130: 
                    131: #define        io_makebits(active, otype, kotype)      \
                    132:        (((active) ? IO_BITS_ACTIVE : 0) | ((otype) << 16) | (kotype))
                    133: 
                    134: /*
                    135:  * Object types: ports, port sets, kernel-loaded ports
                    136:  */
                    137: #define        IOT_PORT                0
                    138: #define IOT_PORT_SET           1
                    139: #define IOT_NUMBER             2               /* number of types used */
                    140: 
                    141: extern zone_t ipc_object_zones[IOT_NUMBER];
                    142: 
                    143: #define        io_alloc(otype)         \
                    144:                ((ipc_object_t) zalloc(ipc_object_zones[(otype)]))
                    145: 
                    146: #if    DIPC || MACH_ASSERT
                    147: /*
                    148:  *     DIPC must intercept the call to deallocate the IPC
                    149:  *     object in case the object in question is a port with
                    150:  *     a dipc_port extension.
                    151:  */
                    152: extern void    io_free(
                    153:                        unsigned int    otype,
                    154:                        ipc_object_t    object);
                    155: 
                    156: #else  /* DIPC || MACH_ASSERT */
                    157: #define        io_free(otype, io)      \
                    158:                zfree(ipc_object_zones[(otype)], (vm_offset_t) (io))
                    159: #endif /* DIPC || MACH_ASSERT */
                    160: 
                    161: /*
                    162:  * Here we depend on the ipc_object being first within the ipc_common_data,
                    163:  * which is first within the rpc_common_data, which in turn must be first
                    164:  * within any kernel data structure needing to lock an ipc_object
                    165:  * (ipc_port and ipc_pset).
                    166:  */
                    167: #if    DIPC && NCPUS == 1
                    168: 
                    169: #define io_lock_init(io) \
                    170:        usimple_lock_init(&(io)-io_lock_data, ETAP_IPC_OBJECT)
                    171: #define        io_lock(io) \
                    172:        usimple_lock(&(io)->io_lock_data)
                    173: #define        io_lock_try(io) \
                    174:        usimple_lock_try(&(io)->io_lock_data)
                    175: #define        io_unlock(io) \
                    176:        usimple_unlock(&(io)->io_lock_data)
                    177: 
                    178: #else  /* DIPC  && NCPUS == 1 */
                    179: 
                    180: #define io_lock_init(io) \
                    181:        mutex_init(&(io)->io_lock_data, ETAP_IPC_OBJECT)
                    182: #define        io_lock(io) \
                    183:        mutex_lock(&(io)->io_lock_data)
                    184: #define        io_lock_try(io) \
                    185:        mutex_try(&(io)->io_lock_data)
                    186: #define        io_unlock(io) \
                    187:        mutex_unlock(&(io)->io_lock_data)
                    188: 
                    189: #endif /* DIPC && NCPUS == 1 */
                    190: 
                    191: #if    NCPUS > 1
                    192: #define _VOLATILE_ volatile
                    193: #else  /* NCPUS > 1 */
                    194: #define _VOLATILE_
                    195: #endif /* NCPUS > 1 */
                    196: 
                    197: #define io_check_unlock(io)                                            \
                    198: MACRO_BEGIN                                                            \
                    199:        _VOLATILE_ ipc_object_refs_t _refs = (io)->io_references;       \
                    200:                                                                        \
                    201:        io_unlock(io);                                                  \
                    202:        if (_refs == 0)                                                 \
                    203:                io_free(io_otype(io), io);                              \
                    204: MACRO_END
                    205: 
                    206: /* Sanity check the ref count.  If it is 0, we may be doubly zfreeing.
                    207:  * If it is larger than max int, it has been corrupted, probably by being
                    208:  * modified into an address (this is architecture dependent, but it's
                    209:  * safe to assume there cannot really be max int references).
                    210:  *
                    211:  * NOTE: The 0 test alone will not catch double zfreeing of ipc_port
                    212:  * structs, because the io_references field is the first word of the struct,
                    213:  * and zfree modifies that to point to the next free zone element.
                    214:  */
                    215: #define IO_MAX_REFERENCES                                              \
                    216:        (unsigned)(~0 ^ (1 << (sizeof(int)*BYTE_SIZE - 1)))
                    217: 
                    218: #define        io_reference(io)                                                \
                    219: MACRO_BEGIN                                                            \
                    220:        assert((io)->io_references < IO_MAX_REFERENCES);                \
                    221:        (io)->io_references++;                                          \
                    222: MACRO_END
                    223: 
                    224: #define        io_release(io)                                                  \
                    225: MACRO_BEGIN                                                            \
                    226:        assert((io)->io_references > 0 &&                               \
                    227:                    (io)->io_references <= IO_MAX_REFERENCES);          \
                    228:        (io)->io_references--;                                          \
                    229: MACRO_END
                    230: 
                    231: /*
                    232:  * Exported interfaces
                    233:  */
                    234: 
                    235: /* Take a reference to an object */
                    236: extern void ipc_object_reference(
                    237:        ipc_object_t    object);
                    238: 
                    239: /* Release a reference to an object */
                    240: extern void ipc_object_release(
                    241:        ipc_object_t    object);
                    242: 
                    243: /* Look up an object in a space */
                    244: extern kern_return_t ipc_object_translate(
                    245:        ipc_space_t             space,
                    246:        mach_port_name_t        name,
                    247:        mach_port_right_t       right,
                    248:        ipc_object_t            *objectp);
                    249: 
                    250: /* Allocate a dead-name entry */
                    251: extern kern_return_t
                    252: ipc_object_alloc_dead(
                    253:        ipc_space_t             space,
                    254:        mach_port_name_t        *namep);
                    255: 
                    256: /*  Allocate a dead-name entry, with a specific name */
                    257: extern kern_return_t ipc_object_alloc_dead_name(
                    258:        ipc_space_t             space,
                    259:        mach_port_name_t        name);
                    260: 
                    261: /* Allocate an object */
                    262: extern kern_return_t ipc_object_alloc(
                    263:        ipc_space_t             space,
                    264:        ipc_object_type_t       otype,
                    265:        mach_port_type_t        type,
                    266:        mach_port_urefs_t       urefs,
                    267:        mach_port_name_t        *namep,
                    268:        ipc_object_t            *objectp);
                    269: 
                    270: /* Allocate an object, with a specific name */
                    271: extern kern_return_t ipc_object_alloc_name(
                    272:        ipc_space_t             space,
                    273:        ipc_object_type_t       otype,
                    274:        mach_port_type_t        type,
                    275:        mach_port_urefs_t       urefs,
                    276:        mach_port_name_t        name,
                    277:        ipc_object_t            *objectp);
                    278: 
                    279: /* Convert a send type name to a received type name */
                    280: extern mach_msg_type_name_t ipc_object_copyin_type(
                    281:        mach_msg_type_name_t    msgt_name);
                    282: 
                    283: /* Copyin a capability from a space */
                    284: extern kern_return_t ipc_object_copyin(
                    285:        ipc_space_t             space,
                    286:        mach_port_name_t        name,
                    287:        mach_msg_type_name_t    msgt_name,
                    288:        ipc_object_t            *objectp);
                    289: 
                    290: /* Copyin a naked capability from the kernel */
                    291: extern void ipc_object_copyin_from_kernel(
                    292:        ipc_object_t            object,
                    293:        mach_msg_type_name_t    msgt_name);
                    294: 
                    295: /* Destroy a naked capability */
                    296: extern void ipc_object_destroy(
                    297:        ipc_object_t            object,
                    298:        mach_msg_type_name_t    msgt_name);
                    299: 
                    300: /* Copyout a capability, placing it into a space */
                    301: extern kern_return_t ipc_object_copyout(
                    302:        ipc_space_t             space,
                    303:        ipc_object_t            object,
                    304:        mach_msg_type_name_t    msgt_name,
                    305:        boolean_t               overflow,
                    306:        mach_port_name_t        *namep);
                    307: 
                    308: /* Copyout a capability with a name, placing it into a space */
                    309: extern kern_return_t ipc_object_copyout_name(
                    310:        ipc_space_t             space,
                    311:        ipc_object_t            object,
                    312:        mach_msg_type_name_t    msgt_name,
                    313:        boolean_t               overflow,
                    314:        mach_port_name_t        name);
                    315: 
                    316: /* Translate/consume the destination right of a message */
                    317: extern void ipc_object_copyout_dest(
                    318:        ipc_space_t             space,
                    319:        ipc_object_t            object,
                    320:        mach_msg_type_name_t    msgt_name,
                    321:        mach_port_name_t        *namep);
                    322: 
                    323: /* Rename an entry in a space */
                    324: extern kern_return_t ipc_object_rename(
                    325:        ipc_space_t             space,
                    326:        mach_port_name_t        oname,
                    327:        mach_port_name_t        nname);
                    328: 
                    329: #if    MACH_RT
                    330: /* Determine if an object is real-time */
                    331: extern boolean_t ipc_object_is_rt(
                    332:        ipc_object_t    object);
                    333: #endif /* MACH_RT */
                    334: 
                    335: #if    MACH_KDB
                    336: /* Pretty-print an ipc object */
                    337: 
                    338: extern void ipc_object_print(
                    339:        ipc_object_t    object);
                    340: 
                    341: #endif /* MACH_KDB */
                    342: 
                    343: #endif /* _IPC_IPC_OBJECT_H_ */

unix.superglobalmegacorp.com

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