Mon Oct 8 12:39:03 2012

Asterisk developer's documentation


optional_api.h

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 2008, Digium, Inc.
00005  *
00006  * Kevin P. Fleming <kpfleming@digium.com>
00007  *
00008  * See http://www.asterisk.org for more information about
00009  * the Asterisk project. Please do not directly contact
00010  * any of the maintainers of this project for assistance;
00011  * the project provides a web site, mailing lists and IRC
00012  * channels for your use.
00013  *
00014  * This program is free software, distributed under the terms of
00015  * the GNU General Public License Version 2. See the LICENSE file
00016  * at the top of the source tree.
00017  */
00018 
00019 #ifndef __ASTERISK_OPTIONAL_API_H
00020 #define __ASTERISK_OPTIONAL_API_H
00021 
00022 /*!
00023  * \file
00024  * \brief Optional API function macros
00025  *
00026  * Some Asterisk API functions are provided by loadable modules, thus,
00027  * they may or may not be available at run time depending on whether the
00028  * providing module has been loaded or not. In addition, there are some
00029  * modules that are consumers of these APIs that *optionally* use them; they
00030  * have only a part of their functionality dependent on the APIs, and can
00031  * provide the remainder even if the APIs are not available.
00032  *
00033  * To accomodate this situation, the AST_OPTIONAL_API macro allows an API
00034  * function to be declared in a special way, if Asterisk being built on a
00035  * platform that supports special compiler and dynamic linker attributes.
00036  * If so the API function will actually be a weak symbol, which means if the
00037  * provider of the API is not loaded, the symbol can still be referenced (unlike a
00038  * strong symbol, which would cause an immediate fault if not defined when
00039  * referenced), but it will return NULL signifying the linker/loader was
00040  * not able to resolve the symbol. In addition, the macro defines a hidden
00041  * 'stub' version of the API call, using a provided function body, and uses
00042  * various methods to make the API function symbol actually resolve to
00043  * that hidden stub, but only when the *real* provider of the symbol has
00044  * not been found.
00045  *
00046  * An example can be found in agi.h:
00047  *
00048  * \code
00049  * AST_OPTIONAL_API(int, ast_agi_register, (struct ast_module *mod, agi_command *cmd),
00050  *                  { return AST_OPTIONAL_API_UNAVAILABLE; });
00051  * \endcode
00052  *
00053  * This defines the 'ast_agi_register' function as an optional API; if a
00054  * consumer of this API is loaded when there is no provider of it, then
00055  * calling this function will actually call the hidden stub, and return
00056  * the value AST_OPTIONAL_API_UNAVAILABLE. This allows the consumer to
00057  * safely know that the API is not available, and to avoid using any
00058  * other APIs from the not-present provider.
00059  *
00060  * In addition to this declaration in the header file, the actual definition of
00061  * the API function must use the AST_OPTIONAL_API_NAME macro to (possibly)
00062  * modify the real name of the API function, depending on the specific
00063  * implementation requirements. The corresponding example from res_agi.c:
00064  *
00065  * \code
00066  * int AST_OPTIONAL_API_NAME(ast_agi_register)(struct ast_module *mod, agi_command *cmd)
00067  * {
00068  * ...
00069  * }
00070  * \endcode
00071  *
00072  * In the module providing the API, the AST_OPTIONAL_API macro must
00073  * be informed that it should not build the hidden stub function or
00074  * apply special aliases to the function prototype; this can be done
00075  * by defining AST_API_MODULE just before including the header file
00076  * containing the AST_OPTIONAL_API macro calls.
00077  *
00078  * \note If the platform does not provide adequate resources,
00079  * then the AST_OPTIONAL_API macro will result in a non-optional function
00080  * definition; this means that any consumers of the API functions so
00081  * defined will require that the provider of the API functions be
00082  * loaded before they can reference the symbols.
00083  *
00084  * WARNING WARNING WARNING WARNING WARNING
00085  *
00086  * You MUST add the AST_MODFLAG_GLOBAL_SYMBOLS to the module for which you
00087  * are enabling optional_api functionality, or it will fail to work.
00088  *
00089  * WARNING WARNING WARNING WARNING WARNING
00090  */
00091 
00092 #define __stringify_1(x)   #x
00093 #define __stringify(x)     __stringify_1(x)
00094 
00095 /*!
00096  * \brief A common value for optional API stub functions to return
00097  *
00098  * This value is defined as INT_MIN, the minimum value for an integer
00099  * (maximum negative value), which can be used by any optional API
00100  * functions that return a signed integer value and would not be
00101  * able to return such a value under normal circumstances.
00102  */
00103 #define AST_OPTIONAL_API_UNAVAILABLE   INT_MIN
00104 
00105 
00106 #if defined(HAVE_ATTRIBUTE_weak_import) || defined(HAVE_ATTRIBUTE_weak)
00107 
00108 /*
00109  * This is the Darwin (Mac OS/X) implementation, that only provides the 'weak'
00110  * or 'weak_import' compiler attribute for weak symbols. On this platform,
00111  *
00112  * - The module providing the API will only provide a '__' prefixed version
00113  *   of the API function to other modules (this will be hidden from the other
00114  *   modules by the macros), so any modules compiled against older versions
00115  *   of the module that provided a non-prefixed version of the API function
00116  *   will fail to link at runtime.
00117  * - In the API module itself, access to the API function without using a
00118  *   prefixed name is provided by a static pointer variable that holds the
00119  *   function address.
00120  * - 'Consumer' modules of the API will use a combination of a weak_import or
00121  *   weak symbol, a local stub function, a pointer variable and a constructor
00122  *   function (which initializes that pointer variable as the module is being
00123  *   loaded) to provide safe, optional access to the API function without any
00124  *   special code being required.
00125  */
00126 
00127 #if defined(HAVE_ATTRIBUTE_weak_import)
00128 #define  __default_attribute  weak_import /* pre-Lion */
00129 #else
00130 #define  __default_attribute  weak        /* Lion-onwards */
00131 #endif
00132 
00133 #define AST_OPTIONAL_API_NAME(name) __##name
00134 
00135 #if defined(AST_API_MODULE)
00136 
00137 #define AST_OPTIONAL_API(result, name, proto, stub) \
00138    result AST_OPTIONAL_API_NAME(name) proto; \
00139    static attribute_unused typeof(AST_OPTIONAL_API_NAME(name)) * const name = AST_OPTIONAL_API_NAME(name);
00140 
00141 #define AST_OPTIONAL_API_ATTR(result, attr, name, proto, stub) \
00142    result __attribute__((attr)) AST_OPTIONAL_API_NAME(name) proto; \
00143    static attribute_unused typeof(AST_OPTIONAL_API_NAME(name)) * const name = AST_OPTIONAL_API_NAME(name);
00144 
00145 #else
00146 
00147 #define AST_OPTIONAL_API(result, name, proto, stub) \
00148    static result __stub__##name proto stub; \
00149    __attribute__((__default_attribute)) typeof(__stub__##name) AST_OPTIONAL_API_NAME(name); \
00150    static attribute_unused typeof(__stub__##name) * name; \
00151    static void __attribute__((constructor)) __init__##name(void) { name = AST_OPTIONAL_API_NAME(name) ? : __stub__##name; }
00152 
00153 #define AST_OPTIONAL_API_ATTR(result, attr, name, proto, stub) \
00154    static __attribute__((attr)) result __stub__##name proto stub; \
00155    __attribute__((attr, __default_attribute)) typeof(__stub__##name) AST_OPTIONAL_API_NAME(name); \
00156    static attribute_unused __attribute__((attr)) typeof(__stub__##name) * name; \
00157    static void __attribute__((constructor)) __init__##name(void) { name = AST_OPTIONAL_API_NAME(name) ? : __stub__##name; }
00158 
00159 #endif
00160 
00161 /* End of Darwin (Mac OS/X) implementation */
00162 
00163 #elif defined(HAVE_ATTRIBUTE_weakref)
00164 
00165 /*
00166  * This is the generic GCC implementation, used when the 'weakref'
00167  * compiler attribute is available. On these platforms:
00168  *
00169  * - The module providing the API will provide a '__' prefixed version
00170  *   of the API function to other modules (this will be hidden from the other
00171  *   modules by the macros), and also a non-prefixed alias so that modules
00172  *   compiled against older versions of the module that provided a non-prefixed
00173  *    version of the API function will continue to link properly.
00174  * - In the API module itself, access to the API function without using a
00175  *   prefixed name is provided by the non-prefixed alias described above.
00176  * - 'Consumer' modules of the API will use a combination of a weakref
00177  *   symbol, a local stub function, a pointer variable and a constructor function
00178  *   (which initializes that pointer variable as the module is being loaded)
00179  *   to provide safe, optional access to the API function without any special
00180  *   code being required.
00181  */
00182 
00183 #define AST_OPTIONAL_API_NAME(name) __##name
00184 
00185 #if defined(AST_API_MODULE)
00186 
00187 #define AST_OPTIONAL_API(result, name, proto, stub) \
00188    result AST_OPTIONAL_API_NAME(name) proto; \
00189    static __attribute__((alias(__stringify(AST_OPTIONAL_API_NAME(name))))) typeof(AST_OPTIONAL_API_NAME(name)) name;
00190 
00191 #define AST_OPTIONAL_API_ATTR(result, attr, name, proto, stub) \
00192    result __attribute__((attr)) AST_OPTIONAL_API_NAME(name) proto; \
00193    static __attribute__((alias(__stringify(AST_OPTIONAL_API_NAME(name))))) typeof(AST_OPTIONAL_API_NAME(name)) name;
00194 
00195 #else
00196 
00197 #define AST_OPTIONAL_API(result, name, proto, stub) \
00198    static result __stub__##name proto stub; \
00199    static __attribute__((weakref(__stringify(AST_OPTIONAL_API_NAME(name))))) typeof(__stub__##name) __ref__##name; \
00200    static attribute_unused typeof(__stub__##name) * name; \
00201    static void __attribute__((constructor)) __init__##name(void) { name = __ref__##name ? : __stub__##name; }
00202 
00203 #define AST_OPTIONAL_API_ATTR(result, attr, name, proto, stub) \
00204    static __attribute__((attr)) result __stub__##name proto stub; \
00205    static __attribute__((attr, weakref(__stringify(AST_OPTIONAL_API_NAME(name))))) typeof(__stub__##name) __ref__##name; \
00206    static attribute_unused __attribute__((attr)) typeof(__stub__##name) * name; \
00207    static void __attribute__((constructor)) __init__##name(void) { name = __ref__##name ? : __stub__##name; }
00208 
00209 #endif
00210 
00211 /* End of GCC implementation */
00212 
00213 #else
00214 
00215 /* This is the non-optional implementation. */
00216 
00217 #define AST_OPTIONAL_API_NAME(name) name
00218 
00219 /*!
00220  * \brief Define an optional API function
00221  *
00222  * \param result The type of result the function returns
00223  * \param name The name of the function
00224  * \param proto The prototype (arguments) of the function
00225  * \param stub The code block that will be used by the hidden stub when needed
00226  *
00227  * Example usage:
00228  * \code
00229  * AST_OPTIONAL_API(int, ast_agi_register, (struct ast_module *mod, agi_command *cmd),
00230  *                  { return AST_OPTIONAL_API_UNAVAILABLE; });
00231  * \endcode     
00232  */
00233 #define AST_OPTIONAL_API(result, name, proto, stub) result AST_OPTIONAL_API_NAME(name) proto
00234 
00235 /*!
00236  * \brief Define an optional API function with compiler attributes
00237  *
00238  * \param result The type of result the function returns
00239  * \param attr Any compiler attributes to be applied to the function (without the __attribute__ wrapper)
00240  * \param name The name of the function
00241  * \param proto The prototype (arguments) of the function
00242  * \param stub The code block that will be used by the hidden stub when needed
00243  */
00244 #define AST_OPTIONAL_API_ATTR(result, attr, name, proto, stub) result __attribute__((attr)) AST_OPTIONAL_API_NAME(name) proto
00245 
00246 /* End of non-optional implementation */
00247 
00248 #endif
00249 
00250 #undef AST_API_MODULE
00251 
00252 #endif /* __ASTERISK_OPTIONAL_API_H */

Generated on Mon Oct 8 12:39:03 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7