diff options
-rw-r--r-- | apps/confbridge/conf_config_parser.c | 6 | ||||
-rw-r--r-- | include/asterisk/bridging_features.h | 12 | ||||
-rw-r--r-- | main/bridging.c | 46 | ||||
-rw-r--r-- | main/features.c | 7 | ||||
-rw-r--r-- | res/parking/parking_bridge_features.c | 1 |
5 files changed, 61 insertions, 11 deletions
diff --git a/apps/confbridge/conf_config_parser.c b/apps/confbridge/conf_config_parser.c index 042968c59..35d96ae31 100644 --- a/apps/confbridge/conf_config_parser.c +++ b/apps/confbridge/conf_config_parser.c @@ -2161,8 +2161,10 @@ int conf_set_menu_to_user(const char *menu_name, struct confbridge_user *user) ao2_ref(menu, +1); pvt->menu = menu; - ast_bridge_dtmf_hook(&user->features, pvt->menu_entry.dtmf, menu_hook_callback, - pvt, menu_hook_destroy, 0); + if (ast_bridge_dtmf_hook(&user->features, pvt->menu_entry.dtmf, + menu_hook_callback, pvt, menu_hook_destroy, 0)) { + menu_hook_destroy(pvt); + } } ao2_unlock(menu); diff --git a/include/asterisk/bridging_features.h b/include/asterisk/bridging_features.h index 1ee13a46a..6399a22fc 100644 --- a/include/asterisk/bridging_features.h +++ b/include/asterisk/bridging_features.h @@ -390,7 +390,7 @@ int ast_bridge_interval_unregister(enum ast_bridge_builtin_interval interval); * \param remove_flags Dictates what situations the hook should be removed. * * \retval 0 on success - * \retval -1 on failure + * \retval -1 on failure (The caller must cleanup any hook_pvt resources.) * * Example usage: * @@ -420,7 +420,7 @@ int ast_bridge_join_hook(struct ast_bridge_features *features, * \param remove_flags Dictates what situations the hook should be removed. * * \retval 0 on success - * \retval -1 on failure + * \retval -1 on failure (The caller must cleanup any hook_pvt resources.) * * Example usage: * @@ -450,7 +450,7 @@ int ast_bridge_leave_hook(struct ast_bridge_features *features, * \param remove_flags Dictates what situations the hook should be removed. * * \retval 0 on success - * \retval -1 on failure + * \retval -1 on failure (The caller must cleanup any hook_pvt resources.) * * Example usage: * @@ -481,7 +481,7 @@ int ast_bridge_hangup_hook(struct ast_bridge_features *features, * \param remove_flags Dictates what situations the hook should be removed. * * \retval 0 on success - * \retval -1 on failure + * \retval -1 on failure (The caller must cleanup any hook_pvt resources.) * * Example usage: * @@ -503,7 +503,7 @@ int ast_bridge_dtmf_hook(struct ast_bridge_features *features, enum ast_bridge_hook_remove_flags remove_flags); /*! - * \brief attach an interval hook to a bridge features structure + * \brief Attach an interval hook to a bridge features structure * * \param features Bridge features structure * \param interval The interval that the hook should execute at in milliseconds @@ -513,7 +513,7 @@ int ast_bridge_dtmf_hook(struct ast_bridge_features *features, * \param remove_flags Dictates what situations the hook should be removed. * * \retval 0 on success - * \retval -1 on failure + * \retval -1 on failure (The caller must cleanup any hook_pvt resources.) * * \code * struct ast_bridge_features features; diff --git a/main/bridging.c b/main/bridging.c index ad730f945..510123753 100644 --- a/main/bridging.c +++ b/main/bridging.c @@ -4893,6 +4893,15 @@ int ast_bridge_dtmf_hook(struct ast_bridge_features *features, /* Once done we put it in the container. */ res = ao2_link(features->dtmf_hooks, hook) ? 0 : -1; + if (res) { + /* + * Could not link the hook into the container. + * + * Remove the hook_pvt destructor call from the hook since we + * are returning failure to install the hook. + */ + hook->destructor = NULL; + } ao2_ref(hook, -1); return res; @@ -4916,6 +4925,15 @@ int ast_bridge_hangup_hook(struct ast_bridge_features *features, /* Once done we put it in the container. */ res = ao2_link(features->hangup_hooks, hook) ? 0 : -1; + if (res) { + /* + * Could not link the hook into the container. + * + * Remove the hook_pvt destructor call from the hook since we + * are returning failure to install the hook. + */ + hook->destructor = NULL; + } ao2_ref(hook, -1); return res; @@ -4939,6 +4957,15 @@ int ast_bridge_join_hook(struct ast_bridge_features *features, /* Once done we put it in the container. */ res = ao2_link(features->join_hooks, hook) ? 0 : -1; + if (res) { + /* + * Could not link the hook into the container. + * + * Remove the hook_pvt destructor call from the hook since we + * are returning failure to install the hook. + */ + hook->destructor = NULL; + } ao2_ref(hook, -1); return res; @@ -4962,6 +4989,15 @@ int ast_bridge_leave_hook(struct ast_bridge_features *features, /* Once done we put it in the container. */ res = ao2_link(features->leave_hooks, hook) ? 0 : -1; + if (res) { + /* + * Could not link the hook into the container. + * + * Remove the hook_pvt destructor call from the hook since we + * are returning failure to install the hook. + */ + hook->destructor = NULL; + } ao2_ref(hook, -1); return res; @@ -5013,11 +5049,17 @@ int ast_bridge_interval_hook(struct ast_bridge_features *features, hook, hook->parms.timer.interval, features); ast_heap_wrlock(features->interval_hooks); res = ast_heap_push(features->interval_hooks, hook); + ast_heap_unlock(features->interval_hooks); if (res) { - /* Could not push the hook onto the heap. */ + /* + * Could not push the hook into the heap + * + * Remove the hook_pvt destructor call from the hook since we + * are returning failure to install the hook. + */ + hook->destructor = NULL; ao2_ref(hook, -1); } - ast_heap_unlock(features->interval_hooks); return res ? -1 : 0; } diff --git a/main/features.c b/main/features.c index c44520c53..ff68b06e5 100644 --- a/main/features.c +++ b/main/features.c @@ -3415,6 +3415,7 @@ static int dynamic_dtmf_hook_add(struct ast_bridge_features *features, unsigned size_t len_moh = ast_strlen_zero(moh_class) ? 0 : strlen(moh_class) + 1; size_t len_feature = strlen(feature_name) + 1; size_t len_data = sizeof(*hook_data) + len_name + len_args + len_moh + len_feature; + int res; /* Fill in application run hook data. */ hook_data = ast_malloc(len_data); @@ -3434,8 +3435,12 @@ static int dynamic_dtmf_hook_add(struct ast_bridge_features *features, unsigned } strcpy(&hook_data->app_name[hook_data->feature_offset], feature_name);/* Safe */ - return ast_bridge_dtmf_hook(features, dtmf, dynamic_dtmf_hook_trip, hook_data, + res = ast_bridge_dtmf_hook(features, dtmf, dynamic_dtmf_hook_trip, hook_data, ast_free_ptr, AST_BRIDGE_HOOK_REMOVE_ON_PULL); + if (res) { + ast_free(hook_data); + } + return res; } static int setup_dynamic_feature(void *obj, void *arg, void *data, int flags) diff --git a/res/parking/parking_bridge_features.c b/res/parking/parking_bridge_features.c index 8e5d739e1..3c0120762 100644 --- a/res/parking/parking_bridge_features.c +++ b/res/parking/parking_bridge_features.c @@ -542,6 +542,7 @@ void parking_set_duration(struct ast_bridge_features *features, struct parked_us if (ast_bridge_interval_hook(features, time_limit, parking_duration_callback, user, parking_duration_cb_destroyer, AST_BRIDGE_HOOK_REMOVE_ON_PULL)) { ast_log(LOG_ERROR, "Failed to apply duration limits to the parking call.\n"); + ao2_ref(user, -1); } } |