Wed Jan 8 2020 09:49:48

Asterisk developer's documentation


optional_api.h
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2008, Digium, Inc.
5  *
6  * Kevin P. Fleming <kpfleming@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18 
19 #ifndef __ASTERISK_OPTIONAL_API_H
20 #define __ASTERISK_OPTIONAL_API_H
21 
22 /*!
23  * \file
24  * \brief Optional API function macros
25  *
26  * Some Asterisk API functions are provided by loadable modules, thus,
27  * they may or may not be available at run time depending on whether the
28  * providing module has been loaded or not. In addition, there are some
29  * modules that are consumers of these APIs that *optionally* use them; they
30  * have only a part of their functionality dependent on the APIs, and can
31  * provide the remainder even if the APIs are not available.
32  *
33  * To accomodate this situation, the AST_OPTIONAL_API macro allows an API
34  * function to be declared in a special way, if Asterisk being built on a
35  * platform that supports special compiler and dynamic linker attributes.
36  * If so the API function will actually be a weak symbol, which means if the
37  * provider of the API is not loaded, the symbol can still be referenced (unlike a
38  * strong symbol, which would cause an immediate fault if not defined when
39  * referenced), but it will return NULL signifying the linker/loader was
40  * not able to resolve the symbol. In addition, the macro defines a hidden
41  * 'stub' version of the API call, using a provided function body, and uses
42  * various methods to make the API function symbol actually resolve to
43  * that hidden stub, but only when the *real* provider of the symbol has
44  * not been found.
45  *
46  * An example can be found in agi.h:
47  *
48  * \code
49  * AST_OPTIONAL_API(int, ast_agi_register, (struct ast_module *mod, agi_command *cmd),
50  * { return AST_OPTIONAL_API_UNAVAILABLE; });
51  * \endcode
52  *
53  * This defines the 'ast_agi_register' function as an optional API; if a
54  * consumer of this API is loaded when there is no provider of it, then
55  * calling this function will actually call the hidden stub, and return
56  * the value AST_OPTIONAL_API_UNAVAILABLE. This allows the consumer to
57  * safely know that the API is not available, and to avoid using any
58  * other APIs from the not-present provider.
59  *
60  * In addition to this declaration in the header file, the actual definition of
61  * the API function must use the AST_OPTIONAL_API_NAME macro to (possibly)
62  * modify the real name of the API function, depending on the specific
63  * implementation requirements. The corresponding example from res_agi.c:
64  *
65  * \code
66  * int AST_OPTIONAL_API_NAME(ast_agi_register)(struct ast_module *mod, agi_command *cmd)
67  * {
68  * ...
69  * }
70  * \endcode
71  *
72  * In the module providing the API, the AST_OPTIONAL_API macro must
73  * be informed that it should not build the hidden stub function or
74  * apply special aliases to the function prototype; this can be done
75  * by defining AST_API_MODULE just before including the header file
76  * containing the AST_OPTIONAL_API macro calls.
77  *
78  * \note If the platform does not provide adequate resources,
79  * then the AST_OPTIONAL_API macro will result in a non-optional function
80  * definition; this means that any consumers of the API functions so
81  * defined will require that the provider of the API functions be
82  * loaded before they can reference the symbols.
83  *
84  * WARNING WARNING WARNING WARNING WARNING
85  *
86  * You MUST add the AST_MODFLAG_GLOBAL_SYMBOLS to the module for which you
87  * are enabling optional_api functionality, or it will fail to work.
88  *
89  * WARNING WARNING WARNING WARNING WARNING
90  */
91 
92 #define __stringify_1(x) #x
93 #define __stringify(x) __stringify_1(x)
94 
95 /*!
96  * \brief A common value for optional API stub functions to return
97  *
98  * This value is defined as INT_MIN, the minimum value for an integer
99  * (maximum negative value), which can be used by any optional API
100  * functions that return a signed integer value and would not be
101  * able to return such a value under normal circumstances.
102  */
103 #define AST_OPTIONAL_API_UNAVAILABLE INT_MIN
104 
105 
106 #if defined(HAVE_ATTRIBUTE_weak_import) || defined(HAVE_ATTRIBUTE_weak)
107 
108 /*
109  * This is the Darwin (Mac OS/X) implementation, that only provides the 'weak'
110  * or 'weak_import' compiler attribute for weak symbols. On this platform,
111  *
112  * - The module providing the API will only provide a '__' prefixed version
113  * of the API function to other modules (this will be hidden from the other
114  * modules by the macros), so any modules compiled against older versions
115  * of the module that provided a non-prefixed version of the API function
116  * will fail to link at runtime.
117  * - In the API module itself, access to the API function without using a
118  * prefixed name is provided by a static pointer variable that holds the
119  * function address.
120  * - 'Consumer' modules of the API will use a combination of a weak_import or
121  * weak symbol, a local stub function, a pointer variable and a constructor
122  * function (which initializes that pointer variable as the module is being
123  * loaded) to provide safe, optional access to the API function without any
124  * special code being required.
125  */
126 
127 #if defined(HAVE_ATTRIBUTE_weak_import)
128 #define __default_attribute weak_import /* pre-Lion */
129 #else
130 #define __default_attribute weak /* Lion-onwards */
131 #endif
132 
133 #define AST_OPTIONAL_API_NAME(name) __##name
134 
135 #if defined(AST_API_MODULE)
136 
137 #define AST_OPTIONAL_API(result, name, proto, stub) \
138  result AST_OPTIONAL_API_NAME(name) proto; \
139  static attribute_unused typeof(AST_OPTIONAL_API_NAME(name)) * const name = AST_OPTIONAL_API_NAME(name);
140 
141 #define AST_OPTIONAL_API_ATTR(result, attr, name, proto, stub) \
142  result __attribute__((attr)) AST_OPTIONAL_API_NAME(name) proto; \
143  static attribute_unused typeof(AST_OPTIONAL_API_NAME(name)) * const name = AST_OPTIONAL_API_NAME(name);
144 
145 #else
146 
147 #define AST_OPTIONAL_API(result, name, proto, stub) \
148  static result __stub__##name proto stub; \
149  __attribute__((__default_attribute)) typeof(__stub__##name) AST_OPTIONAL_API_NAME(name); \
150  static attribute_unused typeof(__stub__##name) * name; \
151  static void __attribute__((constructor)) __init__##name(void) { name = AST_OPTIONAL_API_NAME(name) ? : __stub__##name; }
152 
153 #define AST_OPTIONAL_API_ATTR(result, attr, name, proto, stub) \
154  static __attribute__((attr)) result __stub__##name proto stub; \
155  __attribute__((attr, __default_attribute)) typeof(__stub__##name) AST_OPTIONAL_API_NAME(name); \
156  static attribute_unused __attribute__((attr)) typeof(__stub__##name) * name; \
157  static void __attribute__((constructor)) __init__##name(void) { name = AST_OPTIONAL_API_NAME(name) ? : __stub__##name; }
158 
159 #endif
160 
161 /* End of Darwin (Mac OS/X) implementation */
162 
163 #elif defined(HAVE_ATTRIBUTE_weakref)
164 
165 /*
166  * This is the generic GCC implementation, used when the 'weakref'
167  * compiler attribute is available. On these platforms:
168  *
169  * - The module providing the API will provide a '__' prefixed version
170  * of the API function to other modules (this will be hidden from the other
171  * modules by the macros), and also a non-prefixed alias so that modules
172  * compiled against older versions of the module that provided a non-prefixed
173  * version of the API function will continue to link properly.
174  * - In the API module itself, access to the API function without using a
175  * prefixed name is provided by the non-prefixed alias described above.
176  * - 'Consumer' modules of the API will use a combination of a weakref
177  * symbol, a local stub function, a pointer variable and a constructor function
178  * (which initializes that pointer variable as the module is being loaded)
179  * to provide safe, optional access to the API function without any special
180  * code being required.
181  */
182 
183 #define AST_OPTIONAL_API_NAME(name) __##name
184 
185 #if defined(AST_API_MODULE)
186 
187 #define AST_OPTIONAL_API(result, name, proto, stub) \
188  result AST_OPTIONAL_API_NAME(name) proto; \
189  static __attribute__((alias(__stringify(AST_OPTIONAL_API_NAME(name))))) typeof(AST_OPTIONAL_API_NAME(name)) name;
190 
191 #define AST_OPTIONAL_API_ATTR(result, attr, name, proto, stub) \
192  result __attribute__((attr)) AST_OPTIONAL_API_NAME(name) proto; \
193  static __attribute__((alias(__stringify(AST_OPTIONAL_API_NAME(name))))) typeof(AST_OPTIONAL_API_NAME(name)) name;
194 
195 #else
196 
197 #define AST_OPTIONAL_API(result, name, proto, stub) \
198  static result __stub__##name proto stub; \
199  static __attribute__((weakref(__stringify(AST_OPTIONAL_API_NAME(name))))) typeof(__stub__##name) __ref__##name; \
200  static attribute_unused typeof(__stub__##name) * name; \
201  static void __attribute__((constructor)) __init__##name(void) { name = __ref__##name ? : __stub__##name; }
202 
203 #define AST_OPTIONAL_API_ATTR(result, attr, name, proto, stub) \
204  static __attribute__((attr)) result __stub__##name proto stub; \
205  static __attribute__((attr, weakref(__stringify(AST_OPTIONAL_API_NAME(name))))) typeof(__stub__##name) __ref__##name; \
206  static attribute_unused __attribute__((attr)) typeof(__stub__##name) * name; \
207  static void __attribute__((constructor)) __init__##name(void) { name = __ref__##name ? : __stub__##name; }
208 
209 #endif
210 
211 /* End of GCC implementation */
212 
213 #else
214 
215 /* This is the non-optional implementation. */
216 
217 #define AST_OPTIONAL_API_NAME(name) name
218 
219 /*!
220  * \brief Define an optional API function
221  *
222  * \param result The type of result the function returns
223  * \param name The name of the function
224  * \param proto The prototype (arguments) of the function
225  * \param stub The code block that will be used by the hidden stub when needed
226  *
227  * Example usage:
228  * \code
229  * AST_OPTIONAL_API(int, ast_agi_register, (struct ast_module *mod, agi_command *cmd),
230  * { return AST_OPTIONAL_API_UNAVAILABLE; });
231  * \endcode
232  */
233 #define AST_OPTIONAL_API(result, name, proto, stub) result AST_OPTIONAL_API_NAME(name) proto
234 
235 /*!
236  * \brief Define an optional API function with compiler attributes
237  *
238  * \param result The type of result the function returns
239  * \param attr Any compiler attributes to be applied to the function (without the __attribute__ wrapper)
240  * \param name The name of the function
241  * \param proto The prototype (arguments) of the function
242  * \param stub The code block that will be used by the hidden stub when needed
243  */
244 #define AST_OPTIONAL_API_ATTR(result, attr, name, proto, stub) result __attribute__((attr)) AST_OPTIONAL_API_NAME(name) proto
245 
246 /* End of non-optional implementation */
247 
248 #endif
249 
250 #undef AST_API_MODULE
251 
252 #endif /* __ASTERISK_OPTIONAL_API_H */