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