Annotation of XNU/osfmk/ipc/ipc_port.h, revision 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.