Annotation of coherent/f/usr/include/kernel/bufcall.h, revision 1.1

1.1     ! root        1: #ifndef        __KERNEL_BUFCALL_H__
        !             2: #define        __KERNEL_BUFCALL_H__
        !             3: 
        !             4: /*
        !             5:  * This header file contains a number of definitions aimed at working around
        !             6:  * the enormous problems generated by the existence of callback functions
        !             7:  * as implemented by bufcall (), ie without argument checking. See the
        !             8:  * definition of the str_event structure in <sys/strmlib.h> for a more
        !             9:  * complete discussion of the possible lossage caused by this.
        !            10:  */
        !            11: 
        !            12: /*
        !            13:  *-IMPORTS:
        !            14:  *     <common/ccompat.h>
        !            15:  *             __ANY_ARGS__
        !            16:  *             __INLINE__
        !            17:  *             __USE_INLINE__
        !            18:  *             __PROTO ()
        !            19:  *     <common/xdebug.h>
        !            20:  *             __LOCAL__
        !            21:  *     <sys/stream.h>
        !            22:  *             queue_t
        !            23:  *             toid_t
        !            24:  *             uint_t
        !            25:  */
        !            26: 
        !            27: #include <common/ccompat.h>
        !            28: #include <common/xdebug.h>
        !            29: #include <sys/stream.h>
        !            30: 
        !            31: 
        !            32: /*
        !            33:  * The most appealing solution to this problem is to define a solution that
        !            34:  * works with inline functions to get full argument type checking, and then
        !            35:  * to define an intermediate level for C that simply deals with ensuring that
        !            36:  * the arguments are passed through the regular bufcall () mechanism without
        !            37:  * lossage.
        !            38:  *
        !            39:  * Since the only genuinely safe way of doing this is via the use of stdargs
        !            40:  * (which require that the function be declared that way, in ISO C it is
        !            41:  * distinctly unsafe to cast function pointers such that the argument
        !            42:  * definitions are different). Either an underlying implementation uses this
        !            43:  * form of function call or there must be a forwarding function written that
        !            44:  * does some form of similar hack to perform what is effectively an unsafe
        !            45:  * cast.
        !            46:  *
        !            47:  * In order to make the job of declaring potential fully-type-safe versions
        !            48:  * of the forwarding function, we provide a template-style macro that users
        !            49:  * can try and use.
        !            50:  */
        !            51: 
        !            52: /*
        !            53:  * If you are using this header with an AT&T STREAMS implementation, either
        !            54:  * you can directly call bufcall () (if the AT&T header is not in fact
        !            55:  * prototyped) or you can must bufcall () indirectly through a special
        !            56:  * function safe_bufcall (). If you are using the MWC-supplied STREAMS, then
        !            57:  * bufcall () has been implemented and prototyped such that it does not
        !            58:  * perform any type-checking of the callback or callback-argument arguments.
        !            59:  *
        !            60:  * If you are compiling with the AT&T implementation and have determined that
        !            61:  * it is safe to do so, either define __STDARG_BUFCALL__ below or define it
        !            62:  * in the compiler command line.
        !            63:  */
        !            64: 
        !            65: /* #define __STDARG_BUFCALL__ */
        !            66: 
        !            67: /*
        !            68:  * safe_bufcall () does a bufcall () but effectively overrides any declared
        !            69:  * prototype for bufcall (). In certain cases the underlying bufcall ()
        !            70:  * works this way.
        !            71:  */
        !            72: 
        !            73: #ifdef __STDARG_BUFCALL__
        !            74: 
        !            75: # define       safe_bufcall(s,p,f,a)           bufcall (s, p, f, a)
        !            76: # define       safe_esbbcall(p,f,a)            esbbcall (p, f, a)
        !            77: 
        !            78: #else
        !            79: 
        !            80: __EXTERN_C_BEGIN__
        !            81: 
        !            82: toid_t         safe_bufcall    __PROTO ((uint_t _size, int _pri, ...));
        !            83: toid_t                 safe_esbbcall   __PROTO ((int _pri, ...));
        !            84: 
        !            85: __EXTERN_C_END__
        !            86: 
        !            87: #endif
        !            88: 
        !            89: 
        !            90: /*
        !            91:  * Clients should follow the general form here for declaring wrappers for
        !            92:  * callbacks that are private to clients (in general, the following types
        !            93:  * of callbacks are the only ones that would be visible at anything greater
        !            94:  * than file scope).
        !            95:  */
        !            96: 
        !            97: 
        !            98: #if    __USE_INLINE__ && __USE_PROTO__
        !            99: 
        !           100: # define       __INLINE_BUFCALL(name,type)\
        !           101:     __LOCAL__ __INLINE__ toid_t __CONCAT (bufcall_, name) \
        !           102:                (uint_t _size, int _pri, void (* _func) (type), type _arg) { \
        !           103:       return safe_bufcall (_size, _pri, _func, _arg); \
        !           104:     }
        !           105: # define       __INLINE_ESBBCALL(name,type)\
        !           106:     __LOCAL__ __INLINE__ toid_t __CONCAT (esbbcall_ ,name) \
        !           107:                (int _pri, void (* _func) (type), type _arg) { \
        !           108:       return safe_esbbcall (_pri, _func, arg); \
        !           109:     }
        !           110: 
        !           111: __LOCAL__ __INLINE__
        !           112:   toid_t bufcall_void (uint_t _size, int _pri, void (* _func) (void)) {
        !           113:        return safe_bufcall (_size, _pri, _func, 0);
        !           114: }
        !           115: 
        !           116: __INLINE_BUFCALL (int, int);
        !           117: __INLINE_BUFCALL (long, long);
        !           118: __INLINE_BUFCALL (queue, queue_t *);
        !           119: 
        !           120: __LOCAL__ __INLINE__
        !           121:   toid_t esbbcall_void (int _pri, void (* _func) (void)) {
        !           122:        return safe_esbbcall (_pri, _func, 0);
        !           123: }
        !           124: 
        !           125: __INLINE_ESBBCALL (int, int);
        !           126: __INLINE_ESBBCALL (long, long);
        !           127: __INLINE_ESBBCALL (queue, queue_t *);
        !           128: 
        !           129: #else  /* if ! __USE_INLINE__ || ! __PROTO__ */
        !           130: 
        !           131: # define       bufcall_void(s,p,f)             safe_bufcall (s, p, f, 0)
        !           132: # define       bufcall_int(s,p,f,a)            safe_bufcall (s, p, f,\
        !           133:                                                              (int) (a))
        !           134: # define       bufcall_long(s,p,f,a)           safe_bufcall (s, p, f,\
        !           135:                                                              (long) (a))
        !           136: # define       bufcall_queue(s,p,f,a)          safe_bufcall (s, p, f,\
        !           137:                                                              (queue_t *) (a))
        !           138: 
        !           139: # define       esbbcall_void(p,f)              safe_esbbcall (p, f, 0)
        !           140: # define       esbbcall_int(p,f,a)             safe_esbbcall (p, f, (int) (a))
        !           141: # define       esbbcall_long(p,f,a)            safe_esbbcall (p, f, (long) (a))
        !           142: # define       esbbcall_queue(p,f,a)           safe_esbbcall (p, f, (queue_t *) (a))
        !           143: 
        !           144: #endif /* ! __USE_INLINE__ || ! __PROTO__ */
        !           145: 
        !           146: #endif /* ! defined (__KERNEL_BUFCALL_H__) */

unix.superglobalmegacorp.com

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