diff options
Diffstat (limited to 'main')
-rw-r--r-- | main/bridge_roles.c | 8 | ||||
-rw-r--r-- | main/config.c | 3 | ||||
-rw-r--r-- | main/loader.c | 140 | ||||
-rw-r--r-- | main/optional_api.c | 172 | ||||
-rw-r--r-- | main/rtp_engine.c | 6 |
5 files changed, 184 insertions, 145 deletions
diff --git a/main/bridge_roles.c b/main/bridge_roles.c index a9b95a352..6dbae6fa7 100644 --- a/main/bridge_roles.c +++ b/main/bridge_roles.c @@ -51,12 +51,12 @@ struct bridge_role_option { struct bridge_role { AST_LIST_ENTRY(bridge_role) list; - AST_LIST_HEAD(, bridge_role_option) options; + AST_LIST_HEAD_NOLOCK(, bridge_role_option) options; char role[AST_ROLE_LEN]; }; struct bridge_roles_datastore { - AST_LIST_HEAD(, bridge_role) role_list; + AST_LIST_HEAD_NOLOCK(, bridge_role) role_list; }; /*! @@ -128,6 +128,8 @@ static struct bridge_roles_datastore *setup_bridge_roles_datastore(struct ast_ch return NULL; } + AST_LIST_HEAD_INIT_NOLOCK(&roles_datastore->role_list); + datastore->data = roles_datastore; ast_channel_datastore_add(chan, datastore); return roles_datastore; @@ -264,6 +266,8 @@ static int setup_bridge_role(struct bridge_roles_datastore *roles_datastore, con return -1; } + AST_LIST_HEAD_INIT_NOLOCK(&role->options); + ast_copy_string(role->role, role_name, sizeof(role->role)); AST_LIST_INSERT_TAIL(&roles_datastore->role_list, role, list); diff --git a/main/config.c b/main/config.c index 3fbbacf74..118b9586e 100644 --- a/main/config.c +++ b/main/config.c @@ -2839,8 +2839,6 @@ static void clear_config_maps(void) { struct ast_config_map *map; - SCOPED_MUTEX(lock, &config_lock); - while (config_maps) { map = config_maps; config_maps = config_maps->next; @@ -2894,6 +2892,7 @@ int read_config_maps(void) char *driver, *table, *database, *textpri, *stringp, *tmp; struct ast_flags flags = { CONFIG_FLAG_NOREALTIME }; int pri; + SCOPED_MUTEX(lock, &config_lock); clear_config_maps(); diff --git a/main/loader.c b/main/loader.c index 6b29f0e96..08d9552ff 100644 --- a/main/loader.c +++ b/main/loader.c @@ -87,6 +87,40 @@ </syntax> </managerEventInstance> </managerEvent> + <managerEvent language="en_US" name="Load"> + <managerEventInstance class="EVENT_FLAG_SYSTEM"> + <synopsis>Raised when a module has been loaded in Asterisk.</synopsis> + <syntax> + <parameter name="Module"> + <para>The name of the module that was loaded</para> + </parameter> + <parameter name="Status"> + <para>The result of the load request.</para> + <enumlist> + <enum name="Failure"><para>Module could not be loaded properly</para></enum> + <enum name="Success"><para>Module loaded and configured</para></enum> + <enum name="Decline"><para>Module is not configured</para></enum> + </enumlist> + </parameter> + </syntax> + </managerEventInstance> + </managerEvent> + <managerEvent language="en_US" name="Unload"> + <managerEventInstance class="EVENT_FLAG_SYSTEM"> + <synopsis>Raised when a module has been unloaded in Asterisk.</synopsis> + <syntax> + <parameter name="Module"> + <para>The name of the module that was unloaded</para> + </parameter> + <parameter name="Status"> + <para>The result of the unload request.</para> + <enumlist> + <enum name="Success"><para>Module unloaded successfully</para></enum> + </enumlist> + </parameter> + </syntax> + </managerEventInstance> + </managerEvent> ***/ #ifndef RTLD_NOW @@ -161,6 +195,27 @@ struct ast_module { static AST_DLLIST_HEAD_STATIC(module_list, ast_module); + +struct load_results_map { + int result; + const char *name; +}; + +static const struct load_results_map load_results[] = { + { AST_MODULE_LOAD_SUCCESS, "Success" }, + { AST_MODULE_LOAD_DECLINE, "Decline" }, + { AST_MODULE_LOAD_SKIP, "Skip" }, + { AST_MODULE_LOAD_PRIORITY, "Priority" }, + { AST_MODULE_LOAD_FAILURE, "Failure" }, +}; +#define AST_MODULE_LOAD_UNKNOWN_STRING "Unknown" /* Status string for unknown load status */ + +static void publish_load_message_type(const char* type, const char *name, const char *status); +static void publish_reload_message(const char *name, enum ast_module_reload_result result); +static void publish_load_message(const char *name, enum ast_module_load_result result); +static void publish_unload_message(const char *name, const char* status); + + /* * module_list is cleared by its constructor possibly after * we start accumulating built-in modules, so we need to @@ -1007,6 +1062,7 @@ int ast_unload_resource(const char *resource_name, enum ast_module_unload_mode f unload_dynamic_module(mod); ast_test_suite_event_notify("MODULE_UNLOAD", "Message: %s", resource_name); ast_update_use_count(); + publish_unload_message(resource_name, "Success"); } return res; @@ -1196,29 +1252,30 @@ static void queue_reload_request(const char *module) /*! * \since 12 * \internal - * \brief Publish a \ref stasis message regarding the reload result + * \brief Publish a \ref stasis message regarding the type. */ -static void publish_reload_message(const char *name, enum ast_module_reload_result result) +static void publish_load_message_type(const char* type, const char *name, const char *status) { RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup); RAII_VAR(struct ast_json_payload *, payload, NULL, ao2_cleanup); RAII_VAR(struct ast_json *, json_object, NULL, ast_json_unref); RAII_VAR(struct ast_json *, event_object, NULL, ast_json_unref); - char res_buffer[8]; + + ast_assert(type != NULL); + ast_assert(!ast_strlen_zero(name)); + ast_assert(!ast_strlen_zero(status)); if (!ast_manager_get_generic_type()) { return; } - snprintf(res_buffer, sizeof(res_buffer), "%u", result); - event_object = ast_json_pack("{s: s, s: s}", - "Module", S_OR(name, "All"), - "Status", res_buffer); - json_object = ast_json_pack("{s: s, s: i, s: o}", - "type", "Reload", + event_object = ast_json_pack("{s:s, s:s}", + "Module", name, + "Status", status); + json_object = ast_json_pack("{s:s, s:i, s:o}", + "type", type, "class_type", EVENT_FLAG_SYSTEM, "event", ast_json_ref(event_object)); - if (!json_object) { return; } @@ -1236,6 +1293,54 @@ static void publish_reload_message(const char *name, enum ast_module_reload_resu stasis_publish(ast_manager_get_topic(), message); } +static const char* loadresult2str(enum ast_module_load_result result) +{ + int i; + for (i = 0; i < ARRAY_LEN(load_results); i++) { + if (load_results[i].result == result) { + return load_results[i].name; + } + } + + ast_log(LOG_WARNING, "Failed to find correct load result status. result %d\n", result); + return AST_MODULE_LOAD_UNKNOWN_STRING; +} + +/*! + * \internal + * \brief Publish a \ref stasis message regarding the load result + */ +static void publish_load_message(const char *name, enum ast_module_load_result result) +{ + const char *status; + + status = loadresult2str(result); + + publish_load_message_type("Load", name, status); +} + +/*! + * \internal + * \brief Publish a \ref stasis message regarding the unload result + */ +static void publish_unload_message(const char *name, const char* status) +{ + publish_load_message_type("Unload", name, status); +} + +/*! + * \since 12 + * \internal + * \brief Publish a \ref stasis message regarding the reload result + */ +static void publish_reload_message(const char *name, enum ast_module_reload_result result) +{ + char res_buffer[8]; + + snprintf(res_buffer, sizeof(res_buffer), "%u", result); + publish_load_message_type("Reload", S_OR(name, "All"), res_buffer); +} + enum ast_module_reload_result ast_module_reload(const char *name) { struct ast_module *cur; @@ -1462,10 +1567,7 @@ static enum ast_module_load_result load_resource(const char *resource_name, unsi res |= ast_vector_string_split(&mod->optional_modules, mod->info->optional_modules, ",", 0, strcasecmp); res |= ast_vector_string_split(&mod->enhances, mod->info->enhances, ",", 0, strcasecmp); if (res) { - ast_log(LOG_WARNING, "Failed to initialize dependency structures for module '%s'.\n", resource_name); - unload_dynamic_module(mod); - - return required ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_DECLINE; + goto prestart_error; } } @@ -1484,12 +1586,20 @@ static enum ast_module_load_result load_resource(const char *resource_name, unsi res = start_resource(mod); } + if (ast_fully_booted && !ast_shutdown_final()) { + publish_load_message(resource_name, res); + } + return res; prestart_error: ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name); unload_dynamic_module(mod); - return required ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_DECLINE; + res = required ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_DECLINE; + if (ast_fully_booted && !ast_shutdown_final()) { + publish_load_message(resource_name, res); + } + return res; } int ast_load_resource(const char *resource_name) diff --git a/main/optional_api.c b/main/optional_api.c index 9b9a1a07c..d63129cdd 100644 --- a/main/optional_api.c +++ b/main/optional_api.c @@ -20,6 +20,7 @@ #include "asterisk/optional_api.h" #include "asterisk/utils.h" +#include "asterisk/vector.h" #if defined(OPTIONAL_API) @@ -56,16 +57,18 @@ struct optional_api_user { struct optional_api { /*! Pointer to the implementation function; could be null */ ast_optional_fn impl; - /*! Variable length array of users of this API */ - struct optional_api_user **users; - /*! Allocated size of the \a users array */ - size_t users_maxlen; - /*! Number of entries in the \a users array */ - size_t users_len; + /*! Users of the API */ + AST_VECTOR(, struct optional_api_user *) users; /*! Name of the optional API function */ char symname[]; }; +/*! Vector of \ref optional_api functions */ +AST_VECTOR(, struct optional_api *) apis; + +#define USER_OPTIONAL_REF_CMP(ele, value) (ele->optional_ref == value) +#define OPTIONAL_API_SYMNAME_CMP(ele, value) (!strcmp(ele->symname, value)) + /*! * \brief Free an \ref optional_api_user. * @@ -74,7 +77,7 @@ struct optional_api { static void optional_api_user_destroy(struct optional_api_user *user) { *user->optional_ref = user->stub; - ast_std_free(user); + ast_free(user); } /*! @@ -93,8 +96,10 @@ static struct optional_api_user *optional_api_user_create( struct optional_api_user *user; size_t size = sizeof(*user) + strlen(module) + 1; - user = ast_std_calloc(1, size); + user = ast_calloc(1, size); if (!user) { + ast_do_crash(); + return NULL; } @@ -112,17 +117,15 @@ static struct optional_api_user *optional_api_user_create( */ static void optional_api_destroy(struct optional_api *api) { - while (api->users_len--) { - optional_api_user_destroy(api->users[api->users_len]); - } - ast_std_free(api->users); - api->users = NULL; - api->users_maxlen = 0; - ast_std_free(api); + AST_VECTOR_REMOVE_CMP_UNORDERED(&apis, api, + AST_VECTOR_ELEM_DEFAULT_CMP, AST_VECTOR_ELEM_CLEANUP_NOOP); + AST_VECTOR_CALLBACK_VOID(&api->users, optional_api_user_destroy); + AST_VECTOR_FREE(&api->users); + ast_free(api); } /*! - * \brief Create an \ref optional_api. + * \brief Create and link an \ref optional_api. * * \param symname Name of the optional function. * \return New \ref optional_api. @@ -131,12 +134,12 @@ static void optional_api_destroy(struct optional_api *api) static struct optional_api *optional_api_create(const char *symname) { struct optional_api *api; - size_t size; - size = sizeof(*api) + strlen(symname) + 1; - api = ast_std_calloc(1, size); - if (!api) { - ast_log(LOG_ERROR, "Failed to allocate api\n"); + api = ast_calloc(1, sizeof(*api) + strlen(symname) + 1); + if (!api || AST_VECTOR_APPEND(&apis, api)) { + ast_free(api); + ast_do_crash(); + return NULL; } @@ -145,16 +148,6 @@ static struct optional_api *optional_api_create(const char *symname) return api; } -/*! Array of \ref optional_api functions */ -struct { - /*! Variable length array of API's */ - struct optional_api **list; - /*! Allocated size of the \a list array */ - size_t maxlen; - /*! Number of entries in the \a list array */ - size_t len; -} apis; - /*! * \brief Gets (or creates) the \ref optional_api for the given function. * @@ -164,43 +157,16 @@ struct { */ static struct optional_api *get_api(const char *symname) { - struct optional_api *api; - size_t i; + struct optional_api **api; /* Find one, if we already have it */ - if (apis.list) { - for (i = 0; i < apis.len; ++i) { - if (strcmp(symname, apis.list[i]->symname) == 0) { - return apis.list[i]; - } - } + api = AST_VECTOR_GET_CMP(&apis, symname, OPTIONAL_API_SYMNAME_CMP); + if (api) { + return *api; } /* API not found. Build one */ - api = optional_api_create(symname); - if (!api) { - return NULL; - } - - /* Grow the list, if needed */ - if (apis.len + 1 > apis.maxlen) { - size_t new_maxlen = apis.maxlen ? 2 * apis.maxlen : 1; - struct optional_api **new_list; - - new_list = ast_std_realloc(apis.list, new_maxlen * sizeof(*new_list)); - if (!new_list) { - optional_api_destroy(api); - ast_log(LOG_ERROR, "Failed to allocate api list\n"); - return NULL; - } - - apis.maxlen = new_maxlen; - apis.list = new_list; - } - - apis.list[apis.len++] = api; - - return api; + return optional_api_create(symname); } /*! @@ -232,13 +198,14 @@ static void optional_api_user_relink(struct optional_api_user *user, static void optional_api_set_impl(struct optional_api *api, ast_optional_fn impl) { - size_t i; - api->impl = impl; /* re-link all users */ - for (i = 0; i < api->users_len; ++i) { - optional_api_user_relink(api->users[i], api); + if (AST_VECTOR_SIZE(&api->users)) { + AST_VECTOR_CALLBACK_VOID(&api->users, optional_api_user_relink, api); + } else if (!impl) { + /* No users or impl means we should delete this api. */ + optional_api_destroy(api); } } @@ -247,13 +214,9 @@ void ast_optional_api_provide(const char *symname, ast_optional_fn impl) struct optional_api *api; api = get_api(symname); - if (!api) { - ast_log(LOG_ERROR, "%s: Allocation failed\n", symname); - ast_do_crash(); - return; + if (api) { + optional_api_set_impl(api, impl); } - - optional_api_set_impl(api, impl); } void ast_optional_api_unprovide(const char *symname, ast_optional_fn impl) @@ -261,13 +224,9 @@ void ast_optional_api_unprovide(const char *symname, ast_optional_fn impl) struct optional_api *api; api = get_api(symname); - if (!api) { - ast_log(LOG_ERROR, "%s: Could not find api\n", symname); - ast_do_crash(); - return; + if (api) { + optional_api_set_impl(api, 0); } - - optional_api_set_impl(api, 0); } void ast_optional_api_use(const char *symname, ast_optional_fn *optional_ref, @@ -276,73 +235,36 @@ void ast_optional_api_use(const char *symname, ast_optional_fn *optional_ref, struct optional_api_user *user; struct optional_api *api; - api = get_api(symname); if (!api) { - ast_log(LOG_ERROR, "%s: Allocation failed\n", symname); - ast_do_crash(); return; } user = optional_api_user_create(optional_ref, stub, module); if (!user) { - ast_log(LOG_ERROR, "%s: Allocation failed\n", symname); - ast_do_crash(); return; } /* Add user to the API */ - if (api->users_len + 1 > api->users_maxlen) { - size_t new_maxlen = api->users_maxlen ? 2 * api->users_maxlen : 1; - struct optional_api_user **new_list; - - new_list = ast_std_realloc(api->users, new_maxlen * sizeof(*new_list)); - if (!new_list) { - optional_api_user_destroy(user); - ast_log(LOG_ERROR, "Failed to allocate api list\n"); - ast_do_crash(); - return; - } - - api->users_maxlen = new_maxlen; - api->users = new_list; + if (!AST_VECTOR_APPEND(&api->users, user)) { + optional_api_user_relink(user, api); + } else { + optional_api_user_destroy(user); + ast_do_crash(); } - - api->users[api->users_len++] = user; - - optional_api_user_relink(user, api); } void ast_optional_api_unuse(const char *symname, ast_optional_fn *optional_ref, const char *module) { struct optional_api *api; - size_t i; api = get_api(symname); - if (!api) { - ast_log(LOG_ERROR, "%s: Could not find api\n", symname); - ast_do_crash(); - return; - } - - for (i = 0; i < api->users_len; ++i) { - struct optional_api_user *user = api->users[i]; - - if (user->optional_ref == optional_ref) { - if (*user->optional_ref != user->stub) { - *user->optional_ref = user->stub; - } - - /* Remove from the list */ - api->users[i] = api->users[--api->users_len]; - - optional_api_user_destroy(user); - return; + if (api) { + AST_VECTOR_REMOVE_CMP_UNORDERED(&api->users, optional_ref, USER_OPTIONAL_REF_CMP, optional_api_user_destroy); + if (!api->impl && !AST_VECTOR_SIZE(&api->users)) { + optional_api_destroy(api); } } - - ast_log(LOG_ERROR, "%s: Could not find user %s\n", symname, module); } - #endif /* defined(OPTIONAL_API) */ diff --git a/main/rtp_engine.c b/main/rtp_engine.c index 74243240e..f108a703b 100644 --- a/main/rtp_engine.c +++ b/main/rtp_engine.c @@ -2943,10 +2943,14 @@ static void add_static_payload(int payload, struct ast_format *format, int rtp_c int ast_rtp_engine_load_format(struct ast_format *format) { + char *codec_name = ast_strdupa(ast_format_get_codec_name(format)); + + codec_name = ast_str_to_upper(codec_name); + set_next_mime_type(format, 0, ast_codec_media_type2str(ast_format_get_type(format)), - ast_format_get_codec_name(format), + codec_name, ast_format_get_sample_rate(format)); add_static_payload(-1, format, 0); |