[asterisk-commits] dlee: branch dlee/ASTERISK-22296 r397642 - in /team/dlee/ASTERISK-22296: incl...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Mon Aug 26 10:43:13 CDT 2013
Author: dlee
Date: Mon Aug 26 10:43:11 2013
New Revision: 397642
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=397642
Log:
Try with less magic
Modified:
team/dlee/ASTERISK-22296/include/asterisk/ari.h
team/dlee/ASTERISK-22296/include/asterisk/http_websocket.h
team/dlee/ASTERISK-22296/include/asterisk/optional_api.h
team/dlee/ASTERISK-22296/main/loader.c
team/dlee/ASTERISK-22296/main/optional_api.c
team/dlee/ASTERISK-22296/res/ari/ari_websockets.c
team/dlee/ASTERISK-22296/res/res_ari.c
team/dlee/ASTERISK-22296/res/res_ari_asterisk.c
team/dlee/ASTERISK-22296/res/res_ari_bridges.c
team/dlee/ASTERISK-22296/res/res_ari_channels.c
team/dlee/ASTERISK-22296/res/res_ari_endpoints.c
team/dlee/ASTERISK-22296/res/res_ari_events.c
team/dlee/ASTERISK-22296/res/res_ari_playback.c
team/dlee/ASTERISK-22296/res/res_ari_recordings.c
team/dlee/ASTERISK-22296/res/res_ari_sounds.c
team/dlee/ASTERISK-22296/rest-api-templates/res_ari_resource.c.mustache
Modified: team/dlee/ASTERISK-22296/include/asterisk/ari.h
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22296/include/asterisk/ari.h?view=diff&rev=397642&r1=397641&r2=397642
==============================================================================
--- team/dlee/ASTERISK-22296/include/asterisk/ari.h (original)
+++ team/dlee/ASTERISK-22296/include/asterisk/ari.h Mon Aug 26 10:43:11 2013
@@ -31,6 +31,7 @@
#include "asterisk/http.h"
#include "asterisk/json.h"
+#include "asterisk/http_websocket.h"
/*!
* \brief Configured encoding format for JSON output.
@@ -51,8 +52,6 @@
struct ast_variable *path_vars,
struct ast_variable *headers,
struct ast_ari_response *response);
-
-struct ast_websocket_server;
/*!
* \brief Handler for a single RESTful path segment.
@@ -145,8 +144,6 @@
/*! \brief Abstraction for reading/writing JSON to a WebSocket */
struct ast_ari_websocket_session;
-struct ast_websocket;
-
/*!
* \brief Create an ARI WebSocket session.
*
Modified: team/dlee/ASTERISK-22296/include/asterisk/http_websocket.h
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22296/include/asterisk/http_websocket.h?view=diff&rev=397642&r1=397641&r2=397642
==============================================================================
--- team/dlee/ASTERISK-22296/include/asterisk/http_websocket.h (original)
+++ team/dlee/ASTERISK-22296/include/asterisk/http_websocket.h Mon Aug 26 10:43:11 2013
@@ -92,7 +92,7 @@
* \retval 0 success
* \retval -1 if sub-protocol handler could not be registered
*/
-AST_OPTIONAL_API(int, ast_websocket_add_protocol, (const char *name, ast_websocket_callback callback), {ast_log(LOG_ERROR, "Stubbed!\n"); return -1;});
+AST_OPTIONAL_API(int, ast_websocket_add_protocol, (const char *name, ast_websocket_callback callback), {return -1;});
/*!
* \brief Remove a sub-protocol handler from the default /ws server.
@@ -103,7 +103,7 @@
* \retval 0 success
* \retval -1 if sub-protocol was not found or if callback did not match
*/
-AST_OPTIONAL_API(int, ast_websocket_remove_protocol, (const char *name, ast_websocket_callback callback), {ast_log(LOG_ERROR, "Stubbed!\n"); return -1;});
+AST_OPTIONAL_API(int, ast_websocket_remove_protocol, (const char *name, ast_websocket_callback callback), {return -1;});
/*!
* \brief Add a sub-protocol handler to the given server.
@@ -143,7 +143,7 @@
*
* \note Once an AST_WEBSOCKET_OPCODE_CLOSE opcode is received the socket will be closed
*/
-AST_OPTIONAL_API(int, ast_websocket_read, (struct ast_websocket *session, char **payload, uint64_t *payload_len, enum ast_websocket_opcode *opcode, int *fragmented), { ast_log(LOG_ERROR, "Stubbed!\n"); errno = ENOSYS; return -1;});
+AST_OPTIONAL_API(int, ast_websocket_read, (struct ast_websocket *session, char **payload, uint64_t *payload_len, enum ast_websocket_opcode *opcode, int *fragmented), { errno = ENOSYS; return -1;});
/*!
* \brief Construct and transmit a WebSocket frame
@@ -156,7 +156,7 @@
* \retval 0 if successfully written
* \retval -1 if error occurred
*/
-AST_OPTIONAL_API(int, ast_websocket_write, (struct ast_websocket *session, enum ast_websocket_opcode opcode, char *payload, uint64_t actual_length), { ast_log(LOG_ERROR, "Stubbed!\n"); errno = ENOSYS; return -1;});
+AST_OPTIONAL_API(int, ast_websocket_write, (struct ast_websocket *session, enum ast_websocket_opcode opcode, char *payload, uint64_t actual_length), { errno = ENOSYS; return -1;});
/*!
* \brief Close a WebSocket session by sending a message with the CLOSE opcode and an optional code
@@ -167,7 +167,7 @@
* \retval 0 if successfully written
* \retval -1 if error occurred
*/
-AST_OPTIONAL_API(int, ast_websocket_close, (struct ast_websocket *session, uint16_t reason), { ast_log(LOG_ERROR, "Stubbed!\n"); errno = ENOSYS; return -1;});
+AST_OPTIONAL_API(int, ast_websocket_close, (struct ast_websocket *session, uint16_t reason), { errno = ENOSYS; return -1;});
/*!
* \brief Enable multi-frame reconstruction up to a certain number of bytes
@@ -176,7 +176,7 @@
* \param bytes If a reconstructed payload exceeds the specified number of bytes the payload will be returned
* and upon reception of the next multi-frame a new reconstructed payload will begin.
*/
-AST_OPTIONAL_API(void, ast_websocket_reconstruct_enable, (struct ast_websocket *session, size_t bytes), {ast_log(LOG_ERROR, "Stubbed!\n"); return;});
+AST_OPTIONAL_API(void, ast_websocket_reconstruct_enable, (struct ast_websocket *session, size_t bytes), {return;});
/*!
* \brief Disable multi-frame reconstruction
@@ -186,14 +186,14 @@
* \note If reconstruction is disabled each message that is part of a multi-frame message will be sent up to
* the user when ast_websocket_read is called.
*/
-AST_OPTIONAL_API(void, ast_websocket_reconstruct_disable, (struct ast_websocket *session), {ast_log(LOG_ERROR, "Stubbed!\n"); return;});
+AST_OPTIONAL_API(void, ast_websocket_reconstruct_disable, (struct ast_websocket *session), {return;});
/*!
* \brief Increase the reference count for a WebSocket session
*
* \param session Pointer to the WebSocket session
*/
-AST_OPTIONAL_API(void, ast_websocket_ref, (struct ast_websocket *session), {ast_log(LOG_ERROR, "Stubbed!\n"); return;});
+AST_OPTIONAL_API(void, ast_websocket_ref, (struct ast_websocket *session), {return;});
/*!
* \brief Decrease the reference count for a WebSocket session
@@ -209,14 +209,14 @@
*
* \note You must *not* directly read from or write to this file descriptor. It should only be used for polling.
*/
-AST_OPTIONAL_API(int, ast_websocket_fd, (struct ast_websocket *session), { ast_log(LOG_ERROR, "Stubbed!\n"); errno = ENOSYS; return -1;});
+AST_OPTIONAL_API(int, ast_websocket_fd, (struct ast_websocket *session), { errno = ENOSYS; return -1;});
/*!
* \brief Get the remote address for a WebSocket connected session.
*
* \retval ast_sockaddr Remote address
*/
-AST_OPTIONAL_API(struct ast_sockaddr *, ast_websocket_remote_address, (struct ast_websocket *session), {ast_log(LOG_ERROR, "Stubbed!\n"); return NULL;});
+AST_OPTIONAL_API(struct ast_sockaddr *, ast_websocket_remote_address, (struct ast_websocket *session), {return NULL;});
/*!
* \brief Get whether the WebSocket session is using a secure transport or not.
@@ -224,7 +224,7 @@
* \retval 0 if unsecure
* \retval 1 if secure
*/
-AST_OPTIONAL_API(int, ast_websocket_is_secure, (struct ast_websocket *session), { ast_log(LOG_ERROR, "Stubbed!\n"); errno = ENOSYS; return -1;});
+AST_OPTIONAL_API(int, ast_websocket_is_secure, (struct ast_websocket *session), { errno = ENOSYS; return -1;});
/*!
* \brief Set the socket of a WebSocket session to be non-blocking.
@@ -232,6 +232,6 @@
* \retval 0 on success
* \retval -1 on failure
*/
-AST_OPTIONAL_API(int, ast_websocket_set_nonblock, (struct ast_websocket *session), { ast_log(LOG_ERROR, "Stubbed!\n"); errno = ENOSYS; return -1;});
+AST_OPTIONAL_API(int, ast_websocket_set_nonblock, (struct ast_websocket *session), { errno = ENOSYS; return -1;});
#endif
Modified: team/dlee/ASTERISK-22296/include/asterisk/optional_api.h
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22296/include/asterisk/optional_api.h?view=diff&rev=397642&r1=397641&r2=397642
==============================================================================
--- team/dlee/ASTERISK-22296/include/asterisk/optional_api.h (original)
+++ team/dlee/ASTERISK-22296/include/asterisk/optional_api.h Mon Aug 26 10:43:11 2013
@@ -109,9 +109,12 @@
typedef void (*ast_optional_fn)(void);
-void ast_optional_api_register(ast_optional_fn *function, ast_optional_fn stub,
- const char *symname, const char *module);
-void ast_optional_api_unregister(ast_optional_fn *function);
+void ast_optional_api_provide(const char *symname, ast_optional_fn impl);
+void ast_optional_api_unprovide(const char *symname, ast_optional_fn impl);
+void ast_optional_api_use(const char *symname, ast_optional_fn *optional_ref,
+ ast_optional_fn stub, const char *module);
+void ast_optional_api_unuse(const char *symname, ast_optional_fn *function,
+ const char *module);
void optional_api_onload(void);
void optional_api_onunload(void);
@@ -121,38 +124,51 @@
#if defined(AST_API_MODULE)
/* Module defining the API */
+#define AST_OPTIONAL_API_IMPL_INIT(name) \
+ static void __attribute__((constructor)) __init__##name##_impl(void) { \
+ ast_optional_api_provide(#name, \
+ (ast_optional_fn)AST_OPTIONAL_API_NAME(name)); \
+ } \
+ static void __attribute__((destructor)) __dtor__##name##_impl(void) { \
+ ast_optional_api_unprovide(#name, \
+ (ast_optional_fn)AST_OPTIONAL_API_NAME(name)); \
+ }
+
#define AST_OPTIONAL_API(result, name, proto, stub) \
result AST_OPTIONAL_API_NAME(name) proto; \
- static attribute_unused typeof(AST_OPTIONAL_API_NAME(name)) * const name = AST_OPTIONAL_API_NAME(name)
+ static attribute_unused typeof(AST_OPTIONAL_API_NAME(name)) * const \
+ name = AST_OPTIONAL_API_NAME(name); \
+ AST_OPTIONAL_API_IMPL_INIT(name)
#define AST_OPTIONAL_API_ATTR(result, attr, name, proto, stub) \
result __attribute__((attr)) AST_OPTIONAL_API_NAME(name) proto; \
- static attribute_unused typeof(AST_OPTIONAL_API_NAME(name)) * const name = AST_OPTIONAL_API_NAME(name)
+ static attribute_unused typeof(AST_OPTIONAL_API_NAME(name)) * const \
+ name = AST_OPTIONAL_API_NAME(name); \
+ AST_OPTIONAL_API_IMPL_INIT(name)
#else
/* Module using the API */
#define AST_OPTIONAL_API_INIT(name) \
static void __attribute__((constructor)) __init__##name(void) { \
- ast_verb(3, "%s: %d - init\n", __FILE__, __LINE__); \
- ast_optional_api_register((ast_optional_fn *)&name, \
- (ast_optional_fn)__stub__##name, "__" #name, \
+ ast_optional_api_use(#name, (ast_optional_fn *)&name, \
+ (ast_optional_fn)__stub__##name, \
AST_MODULE); \
} \
static void __attribute__((destructor)) __dtor__##name(void) { \
- ast_verb(3, "%s: %d - dtor\n", __FILE__, __LINE__); \
- ast_optional_api_unregister((ast_optional_fn *)&name); \
+ ast_optional_api_unuse(#name, (ast_optional_fn *)&name, \
+ AST_MODULE); \
}
+
+#define AST_OPTIONAL_API(result, name, proto, stub) \
+ static result __stub__##name proto stub; \
+ static attribute_unused \
+ typeof(__stub__##name) * name; \
+ AST_OPTIONAL_API_INIT(name)
#define AST_OPTIONAL_API_ATTR(result, attr, name, proto, stub) \
static __attribute__((attr)) result __stub__##name proto stub; \
static attribute_unused __attribute__((attr)) \
- typeof(__stub__##name) * name; \
- AST_OPTIONAL_API_INIT(name)
-
-#define AST_OPTIONAL_API(result, name, proto, stub) \
- static result __stub__##name proto stub; \
- static attribute_unused \
typeof(__stub__##name) * name; \
AST_OPTIONAL_API_INIT(name)
Modified: team/dlee/ASTERISK-22296/main/loader.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22296/main/loader.c?view=diff&rev=397642&r1=397641&r2=397642
==============================================================================
--- team/dlee/ASTERISK-22296/main/loader.c (original)
+++ team/dlee/ASTERISK-22296/main/loader.c Mon Aug 26 10:43:11 2013
@@ -415,7 +415,8 @@
if (lib)
while (!dlclose(lib));
- /* If mod offered an optional API, it's not there any more! */
+ /* If mod offered an optional API, it's not there any more!
+ * Scan optional_api users for potential unloads. */
optional_api_onunload();
}
@@ -449,7 +450,6 @@
if (missing_so)
strcat(resource_being_loaded->resource, ".so");
- ast_verb(3, "Inspecting %s\n", fn);
if (!(lib = dlopen(fn, RTLD_LAZY | RTLD_LOCAL))) {
ast_log(LOG_WARNING, "Error loading module '%s': %s\n", resource_in, dlerror());
ast_free(resource_being_loaded);
@@ -477,7 +477,6 @@
/* if we are being asked only to load modules that provide global symbols,
and this one does not, then close it and return */
if (global_symbols_only && !wants_global) {
- ast_verb(3, " Unloading %s\n", fn);
while (!dlclose(lib));
return NULL;
}
@@ -503,7 +502,6 @@
}
#endif
- ast_verb(3, " Unloading %s\n", fn);
while (!dlclose(lib));
resource_being_loaded = NULL;
@@ -515,7 +513,6 @@
if (missing_so)
strcat(resource_being_loaded->resource, ".so");
- ast_verb(3, "Opening %s\n", fn);
if (!(lib = dlopen(fn, wants_global ? RTLD_LAZY | RTLD_GLOBAL : RTLD_NOW | RTLD_LOCAL))) {
ast_log(LOG_WARNING, "Error loading module '%s': %s\n", resource_in, dlerror());
ast_free(resource_being_loaded);
@@ -1104,6 +1101,9 @@
if(!(resource_heap = ast_heap_create(8, mod_load_cmp, -1))) {
return -1;
}
+
+ ast_verb(1, "Loading modules%s exporting global symbols\n",
+ global_symbols ? "" : " not");
/* first, add find and add modules to heap */
AST_LIST_TRAVERSE_SAFE_BEGIN(load_order, order, entry) {
@@ -1279,6 +1279,9 @@
if (load_count)
ast_log(LOG_NOTICE, "%d modules will be loaded.\n", load_count);
+ ast_verb(1, "Loading %spreload modules\n",
+ preload_only ? "" : "non-");
+
/* first, load only modules that provide global symbols */
if ((res = load_resource_list(&load_order, 1, &modulecount)) < 0) {
goto done;
Modified: team/dlee/ASTERISK-22296/main/optional_api.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22296/main/optional_api.c?view=diff&rev=397642&r1=397641&r2=397642
==============================================================================
--- team/dlee/ASTERISK-22296/main/optional_api.c (original)
+++ team/dlee/ASTERISK-22296/main/optional_api.c Mon Aug 26 10:43:11 2013
@@ -20,144 +20,262 @@
ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+#include "asterisk/astobj2.h"
+#include "asterisk/lock.h"
#include "asterisk/optional_api.h"
-#include "asterisk/linkedlists.h"
#include "asterisk/utils.h"
-#include <dlfcn.h>
-
-struct optional_ref {
- AST_LIST_ENTRY(optional_ref) list;
-
- ast_optional_fn *function;
+struct optional_api_user {
+ ast_optional_fn *optional_ref;
ast_optional_fn stub;
- const char *module;
+ char module[];
+};
+
+struct optional_api {
+ ast_optional_fn impl;
+ struct ao2_container *users;
char symname[];
};
-static AST_LIST_HEAD_STATIC(optional_references, optional_ref);
-
-static void optional_ref_dtor(void *obj)
-{
- struct optional_ref *ref = obj;
- *(ref->function) = ref->stub;
-}
-
-static struct optional_ref *optional_ref_create(ast_optional_fn *function,
- ast_optional_fn stub, const char *symname, const char *module)
-{
- RAII_VAR(struct optional_ref *, ref, NULL, ao2_cleanup);
-
- size_t size = sizeof(*ref) + strlen(symname) + 1;
- ref = ao2_alloc(size, optional_ref_dtor);
- if (!ref) {
- return NULL;
- }
-
- ref->function = function;
- ref->stub = stub;
- /* Safe strcpy */
- strcpy(ref->symname, symname);
- /* Module name is a #define; safe to reference without copy */
- ref->module = module;
-
- return ao2_bump(ref);
-}
-
-static void optional_ref_update(struct optional_ref *ref)
-{
- void *real_fn;
-
- if (!ref) {
+static void optional_api_dtor(void *obj)
+{
+ struct optional_api *api = obj;
+
+ ao2_cleanup(api->users);
+ api->users = NULL;
+}
+
+static struct optional_api *optional_api_create(const char *symname)
+{
+ RAII_VAR(struct optional_api *, api, NULL, ao2_cleanup);
+ size_t size;
+
+ if (!symname) {
+ return NULL;
+ }
+ size = sizeof(*api) + strlen(symname) + 1;
+
+ api = ao2_alloc_options(size, optional_api_dtor, OBJ_NOLOCK);
+ if (!api) {
+ return NULL;
+ }
+
+ api->users = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_NOLOCK, 0,
+ NULL, NULL);
+ if (!api->users) {
+ return NULL;
+ }
+
+ return ao2_bump(api);
+}
+
+static void optional_api_user_dtor(void *obj) {
+ struct optional_api_user *user = obj;
+
+ ast_assert(*user->optional_ref == user->stub);
+}
+
+static struct optional_api_user *optional_api_user_create(
+ ast_optional_fn *optional_ref, ast_optional_fn stub, const char *module)
+{
+ RAII_VAR(struct optional_api_user *, user, NULL, ao2_cleanup);
+ size_t size = sizeof(*user) + strlen(module) + 1;
+
+ user = ao2_alloc_options(size, optional_api_user_dtor,
+ AO2_ALLOC_OPT_LOCK_NOLOCK);
+ if (!user) {
+ return NULL;
+ }
+
+ user->optional_ref = optional_ref;
+ user->stub = stub;
+ /* safe strcpy */
+ strcpy(user->module, module);
+
+ return ao2_bump(user);
+
+}
+
+static struct ao2_container *_apis;
+
+static int optional_api_sort(const void *obj_left, const void *obj_right,
+ int flags)
+{
+ const struct optional_api *object_left = obj_left;
+ const struct optional_api *object_right = obj_right;
+ const char *right_key = obj_right;
+ int cmp;
+
+ switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
+ case OBJ_POINTER:
+ right_key = object_right->symname;
+ /* Fall through */
+ case OBJ_KEY:
+ cmp = strcmp(object_left->symname, right_key);
+ break;
+ case OBJ_PARTIAL_KEY:
+ /*
+ * We could also use a partial key struct containing a length
+ * so strlen() does not get called for every comparison instead.
+ */
+ cmp = strncmp(object_left->symname, right_key, strlen(right_key));
+ break;
+ default:
+ /* Sort can only work on something with a full or partial key. */
+ ast_assert(0);
+ cmp = 0;
+ break;
+ }
+ return cmp;
+}
+
+static void optional_api_cleanup(void)
+{
+ ao2_cleanup(_apis);
+ _apis = NULL;
+}
+
+static struct ao2_container *get_apis(void)
+{
+ /* optional_api calls can happen before main() starts, or during
+ * dlopen() as modules are loaded. These are (or at least should be)
+ * synchronized, so no lock is needed here.
+ *
+ * Which is good, because there's no consistent way to build a global
+ * mutex that we know will be initialized before get_apis() is first
+ * called.
+ */
+ if (_apis) {
+ return _apis;
+ }
+
+ ast_register_cleanup(optional_api_cleanup);
+
+ _apis = ao2_container_alloc_rbtree(AO2_ALLOC_OPT_LOCK_MUTEX,
+ AO2_CONTAINER_ALLOC_OPT_DUPS_REJECT, optional_api_sort,
+ NULL);
+ if (!_apis) {
+ ast_log(LOG_ERROR, "Failed to allocate apis\n");
+ ast_assert(0);
+ return NULL;
+ }
+
+ return 0;
+}
+
+static void optional_api_user_relink(struct optional_api_user *user,
+ struct optional_api *api)
+{
+ if (api->impl) {
+ ast_verb(4, "%s: linking %s\n", api->symname, user->module);
+ *user->optional_ref = api->impl;
+ } else {
+ ast_verb(4, "%s: stubbing %s\n", api->symname, user->module);
+ *user->optional_ref = user->stub;
+ }
+}
+
+static int optional_api_user_relink_cb(void *obj, void *arg, int flags)
+{
+ struct optional_api_user *user = obj;
+ struct optional_api *api = arg;
+
+ optional_api_user_relink(user, api);
+ return 0;
+}
+
+void ast_optional_api_provide(const char *symname, ast_optional_fn impl)
+{
+ RAII_VAR(struct optional_api *, api, NULL, ao2_cleanup);
+ SCOPED_AO2LOCK(lock, get_apis());
+
+ ast_verb(4, "%s: providing\n", symname);
+
+ api = ao2_find(get_apis(), symname, OBJ_NOLOCK);
+ if (!api) {
+ api = optional_api_create(symname);
+ if (!api) {
+ ast_log(LOG_ERROR, "%s: Allocation failed\n", symname);
+ return;
+ }
+ }
+
+ api->impl = impl;
+ ao2_callback(api->users, OBJ_NODATA, optional_api_user_relink_cb, impl);
+}
+
+void ast_optional_api_unprovide(const char *symname, ast_optional_fn impl)
+{
+ RAII_VAR(struct optional_api *, api, NULL, ao2_cleanup);
+ SCOPED_AO2LOCK(lock, get_apis());
+
+ ast_verb(4, "%s: un-providing\n", symname);
+
+ api = ao2_find(get_apis(), symname, OBJ_NOLOCK);
+ if (!api) {
+ ast_log(LOG_ERROR, "%s: Could not find api\n", symname);
return;
}
- real_fn = dlsym(RTLD_DEFAULT, ref->symname);
- if (real_fn) {
- if (*ref->function == ref->stub) {
- ast_verb(4, "Filling stub %s:%s\n", ref->module,
- ref->symname);
+ api->impl = 0;
+ ao2_callback(api->users, OBJ_NODATA, optional_api_user_relink_cb, impl);
+}
+
+void ast_optional_api_use(const char *symname, ast_optional_fn *optional_ref,
+ ast_optional_fn stub, const char *module)
+{
+ RAII_VAR(struct optional_api_user *, user, NULL, ao2_cleanup);
+ RAII_VAR(struct optional_api *, api, NULL, ao2_cleanup);
+ SCOPED_AO2LOCK(lock, get_apis());
+
+ ast_verb(4, "%s: use by %s\n", symname, module);
+
+ api = ao2_find(get_apis(), symname, OBJ_NOLOCK);
+ if (!api) {
+ api = optional_api_create(symname);
+ if (!api) {
+ ast_log(LOG_ERROR, "%s: Allocation failed\n", symname);
+ return;
}
- *ref->function = real_fn;
- } else {
- if (*ref->function != ref->stub) {
- ast_verb(4, "Stubbing %s:%s\n", ref->module,
- ref->symname);
- }
- *ref->function = ref->stub;
- }
-}
-
-void ast_optional_api_register(ast_optional_fn *function, ast_optional_fn stub,
- const char *symname, const char *module)
-{
- RAII_VAR(struct optional_ref *, ref, NULL, ao2_cleanup);
-
- ast_verb(4, "Registering stub %s:%s\n", module, symname);
-
- /* Default the function to the stub */
- *function = stub;
-
- ref = optional_ref_create(function, stub, symname, module);
- if (!ref) {
- ast_log(LOG_ERROR, "Failed to fill in stub for %s:%s\n",
- ref->module, symname);
+ }
+
+ user = optional_api_user_create(optional_ref, stub, module);
+ if (!user) {
+ ast_log(LOG_ERROR, "%s: Allocation failed\n", symname);
return;
}
- /* Go ahead and link it, if we can */
- optional_ref_update(ref);
-
- AST_LIST_LOCK(&optional_references);
- AST_LIST_INSERT_HEAD(&optional_references, ao2_bump(ref), list);
- AST_LIST_UNLOCK(&optional_references);
-}
-
-void ast_optional_api_unregister(ast_optional_fn *function)
-{
- struct optional_ref *ref;
-
- ast_verb(4, "unref\n");
-
- AST_LIST_LOCK(&optional_references);
- AST_LIST_TRAVERSE_SAFE_BEGIN(&optional_references, ref, list) {
- if (ref->function == function) {
- ast_verb(5, "Unregistering stub %s:%s\n",
- ref->module, ref->symname);
- AST_LIST_REMOVE_CURRENT(list);
- ao2_cleanup(ref);
- }
- }
- AST_LIST_TRAVERSE_SAFE_END;
- AST_LIST_UNLOCK(&optional_references);
-}
-
-void optional_api_onload(void)
-{
- struct optional_ref *ref;
-
- AST_LIST_LOCK(&optional_references);
- AST_LIST_TRAVERSE_SAFE_BEGIN(&optional_references, ref, list) {
- /* Update any refs that are pointing to their proxy */
- if (*ref->function == ref->stub) {
- optional_ref_update(ref);
- }
- }
- AST_LIST_TRAVERSE_SAFE_END;
- AST_LIST_UNLOCK(&optional_references);
-}
-
-void optional_api_onunload(void)
-{
- struct optional_ref *ref;
-
- AST_LIST_LOCK(&optional_references);
- AST_LIST_TRAVERSE_SAFE_BEGIN(&optional_references, ref, list) {
- /* Update any refs that are pointing to a real impl */
- if (*ref->function != ref->stub) {
- optional_ref_update(ref);
- }
- }
- AST_LIST_TRAVERSE_SAFE_END;
- AST_LIST_UNLOCK(&optional_references);
-}
+ optional_api_user_relink(user, api);
+}
+
+static int optional_api_user_find_and_unuse(void *obj, void *arg, int flags)
+{
+ struct optional_api_user *user = obj;
+ ast_optional_fn *optional_ref = arg;
+
+ if (user->optional_ref != optional_ref) {
+ return 0;
+ }
+
+ ast_verb(4, " Stubbing %s\n", user->module);
+ *user->optional_ref = user->stub;
+ return CMP_MATCH | CMP_STOP;
+}
+
+void ast_optional_api_unuse(const char *symname, ast_optional_fn *optional_ref,
+ const char *module)
+{
+ RAII_VAR(struct optional_api *, api, NULL, ao2_cleanup);
+ SCOPED_AO2LOCK(lock, get_apis());
+
+ ast_verb(4, "%s: un-use by %s\n", symname, module);
+
+ api = ao2_find(get_apis(), symname, OBJ_NOLOCK);
+ if (!api) {
+ ast_log(LOG_ERROR, "%s: Could not find api\n", symname);
+ return;
+ }
+
+ ao2_callback(api->users, OBJ_NOLOCK | OBJ_UNLINK | OBJ_NODATA,
+ optional_api_user_find_and_unuse, optional_ref);
+}
Modified: team/dlee/ASTERISK-22296/res/ari/ari_websockets.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22296/res/ari/ari_websockets.c?view=diff&rev=397642&r1=397641&r2=397642
==============================================================================
--- team/dlee/ASTERISK-22296/res/ari/ari_websockets.c (original)
+++ team/dlee/ASTERISK-22296/res/ari/ari_websockets.c Mon Aug 26 10:43:11 2013
@@ -20,9 +20,8 @@
ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+#include "asterisk/astobj2.h"
#include "asterisk/ari.h"
-#include "asterisk/astobj2.h"
-#include "asterisk/http_websocket.h"
/*! \file
*
Modified: team/dlee/ASTERISK-22296/res/res_ari.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22296/res/res_ari.c?view=diff&rev=397642&r1=397641&r2=397642
==============================================================================
--- team/dlee/ASTERISK-22296/res/res_ari.c (original)
+++ team/dlee/ASTERISK-22296/res/res_ari.c Mon Aug 26 10:43:11 2013
@@ -124,12 +124,11 @@
ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-#include "ari/internal.h"
-#include "asterisk/ari.h"
#include "asterisk/astobj2.h"
-#include "asterisk/http_websocket.h"
#include "asterisk/module.h"
#include "asterisk/paths.h"
+#include "asterisk/ari.h"
+#include "ari/internal.h"
#include <string.h>
#include <sys/stat.h>
Modified: team/dlee/ASTERISK-22296/res/res_ari_asterisk.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22296/res/res_ari_asterisk.c?view=diff&rev=397642&r1=397641&r2=397642
==============================================================================
--- team/dlee/ASTERISK-22296/res/res_ari_asterisk.c (original)
+++ team/dlee/ASTERISK-22296/res/res_ari_asterisk.c Mon Aug 26 10:43:11 2013
@@ -41,11 +41,10 @@
ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-#include "ari/resource_asterisk.h"
#include "asterisk/app.h"
-#include "asterisk/http_websocket.h"
#include "asterisk/module.h"
#include "asterisk/stasis_app.h"
+#include "ari/resource_asterisk.h"
#if defined(AST_DEVMODE)
#include "ari/ari_model_validators.h"
#endif
Modified: team/dlee/ASTERISK-22296/res/res_ari_bridges.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22296/res/res_ari_bridges.c?view=diff&rev=397642&r1=397641&r2=397642
==============================================================================
--- team/dlee/ASTERISK-22296/res/res_ari_bridges.c (original)
+++ team/dlee/ASTERISK-22296/res/res_ari_bridges.c Mon Aug 26 10:43:11 2013
@@ -41,11 +41,10 @@
ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-#include "ari/resource_bridges.h"
#include "asterisk/app.h"
-#include "asterisk/http_websocket.h"
#include "asterisk/module.h"
#include "asterisk/stasis_app.h"
+#include "ari/resource_bridges.h"
#if defined(AST_DEVMODE)
#include "ari/ari_model_validators.h"
#endif
Modified: team/dlee/ASTERISK-22296/res/res_ari_channels.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22296/res/res_ari_channels.c?view=diff&rev=397642&r1=397641&r2=397642
==============================================================================
--- team/dlee/ASTERISK-22296/res/res_ari_channels.c (original)
+++ team/dlee/ASTERISK-22296/res/res_ari_channels.c Mon Aug 26 10:43:11 2013
@@ -41,11 +41,10 @@
ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-#include "ari/resource_channels.h"
#include "asterisk/app.h"
-#include "asterisk/http_websocket.h"
#include "asterisk/module.h"
#include "asterisk/stasis_app.h"
+#include "ari/resource_channels.h"
#if defined(AST_DEVMODE)
#include "ari/ari_model_validators.h"
#endif
Modified: team/dlee/ASTERISK-22296/res/res_ari_endpoints.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22296/res/res_ari_endpoints.c?view=diff&rev=397642&r1=397641&r2=397642
==============================================================================
--- team/dlee/ASTERISK-22296/res/res_ari_endpoints.c (original)
+++ team/dlee/ASTERISK-22296/res/res_ari_endpoints.c Mon Aug 26 10:43:11 2013
@@ -41,11 +41,10 @@
ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-#include "ari/resource_endpoints.h"
#include "asterisk/app.h"
-#include "asterisk/http_websocket.h"
#include "asterisk/module.h"
#include "asterisk/stasis_app.h"
+#include "ari/resource_endpoints.h"
#if defined(AST_DEVMODE)
#include "ari/ari_model_validators.h"
#endif
Modified: team/dlee/ASTERISK-22296/res/res_ari_events.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22296/res/res_ari_events.c?view=diff&rev=397642&r1=397641&r2=397642
==============================================================================
--- team/dlee/ASTERISK-22296/res/res_ari_events.c (original)
+++ team/dlee/ASTERISK-22296/res/res_ari_events.c Mon Aug 26 10:43:11 2013
@@ -41,11 +41,10 @@
ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-#include "ari/resource_events.h"
#include "asterisk/app.h"
-#include "asterisk/http_websocket.h"
#include "asterisk/module.h"
#include "asterisk/stasis_app.h"
+#include "ari/resource_events.h"
#if defined(AST_DEVMODE)
#include "ari/ari_model_validators.h"
#endif
Modified: team/dlee/ASTERISK-22296/res/res_ari_playback.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22296/res/res_ari_playback.c?view=diff&rev=397642&r1=397641&r2=397642
==============================================================================
--- team/dlee/ASTERISK-22296/res/res_ari_playback.c (original)
+++ team/dlee/ASTERISK-22296/res/res_ari_playback.c Mon Aug 26 10:43:11 2013
@@ -41,11 +41,10 @@
ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-#include "ari/resource_playback.h"
#include "asterisk/app.h"
-#include "asterisk/http_websocket.h"
#include "asterisk/module.h"
#include "asterisk/stasis_app.h"
+#include "ari/resource_playback.h"
#if defined(AST_DEVMODE)
#include "ari/ari_model_validators.h"
#endif
Modified: team/dlee/ASTERISK-22296/res/res_ari_recordings.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22296/res/res_ari_recordings.c?view=diff&rev=397642&r1=397641&r2=397642
==============================================================================
--- team/dlee/ASTERISK-22296/res/res_ari_recordings.c (original)
+++ team/dlee/ASTERISK-22296/res/res_ari_recordings.c Mon Aug 26 10:43:11 2013
@@ -41,11 +41,10 @@
ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-#include "ari/resource_recordings.h"
#include "asterisk/app.h"
-#include "asterisk/http_websocket.h"
#include "asterisk/module.h"
#include "asterisk/stasis_app.h"
+#include "ari/resource_recordings.h"
#if defined(AST_DEVMODE)
#include "ari/ari_model_validators.h"
#endif
Modified: team/dlee/ASTERISK-22296/res/res_ari_sounds.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22296/res/res_ari_sounds.c?view=diff&rev=397642&r1=397641&r2=397642
==============================================================================
--- team/dlee/ASTERISK-22296/res/res_ari_sounds.c (original)
+++ team/dlee/ASTERISK-22296/res/res_ari_sounds.c Mon Aug 26 10:43:11 2013
@@ -41,11 +41,10 @@
ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-#include "ari/resource_sounds.h"
#include "asterisk/app.h"
-#include "asterisk/http_websocket.h"
#include "asterisk/module.h"
#include "asterisk/stasis_app.h"
+#include "ari/resource_sounds.h"
#if defined(AST_DEVMODE)
#include "ari/ari_model_validators.h"
#endif
Modified: team/dlee/ASTERISK-22296/rest-api-templates/res_ari_resource.c.mustache
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ASTERISK-22296/rest-api-templates/res_ari_resource.c.mustache?view=diff&rev=397642&r1=397641&r2=397642
==============================================================================
--- team/dlee/ASTERISK-22296/rest-api-templates/res_ari_resource.c.mustache (original)
+++ team/dlee/ASTERISK-22296/rest-api-templates/res_ari_resource.c.mustache Mon Aug 26 10:43:11 2013
@@ -46,11 +46,10 @@
ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-#include "ari/resource_{{name}}.h"
#include "asterisk/app.h"
-#include "asterisk/http_websocket.h"
#include "asterisk/module.h"
#include "asterisk/stasis_app.h"
+#include "ari/resource_{{name}}.h"
#if defined(AST_DEVMODE)
#include "ari/ari_model_validators.h"
#endif
More information about the asterisk-commits
mailing list