summaryrefslogtreecommitdiff
path: root/main/manager.c
diff options
context:
space:
mode:
authorCorey Farrell <git@cfware.com>2017-12-29 19:24:02 -0500
committerCorey Farrell <git@cfware.com>2018-01-03 17:23:36 -0500
commit55f1d69c43d2c6c87eec50fd3eed7a77ba2e912b (patch)
tree0749060ca9d29dc796152f1654a340f091f4f600 /main/manager.c
parent7f4facc5e4a96ccae10283da998044becc4fbe11 (diff)
loader: Create ast_module_running_ref.
This function returns NULL if the module in question is not running. I did not change ast_module_ref as most callers do not check the result and they always call ast_module_unref. Make use of this function when running registered items from: * app_stack API's * bridge technologies * CLI commands * File formats * Manager Actions * RTP engines * Sorcery Wizards * Timing Interfaces * Translators * AGI Commands * Fax Technologies ASTERISK-20346 #close Change-Id: Ia16fd28e188b2fc0b9d18b8a5d9cacc31df73fcc
Diffstat (limited to 'main/manager.c')
-rw-r--r--main/manager.c71
1 files changed, 39 insertions, 32 deletions
diff --git a/main/manager.c b/main/manager.c
index 576978c31..3aa910501 100644
--- a/main/manager.c
+++ b/main/manager.c
@@ -2923,34 +2923,41 @@ int ast_hook_send_action(struct manager_custom_hook *hook, const char *msg)
}
action = astman_get_header(&m, "Action");
- if (strcasecmp(action, "login")) {
+
+ do {
+ if (!strcasecmp(action, "login")) {
+ break;
+ }
+
act_found = action_find(action);
- if (act_found) {
- /*
- * we have to simulate a session for this action request
- * to be able to pass it down for processing
- * This is necessary to meet the previous design of manager.c
- */
- s.hook = hook;
+ if (!act_found) {
+ break;
+ }
- ao2_lock(act_found);
- if (act_found->registered && act_found->func) {
- if (act_found->module) {
- ast_module_ref(act_found->module);
- }
- ao2_unlock(act_found);
+ /*
+ * we have to simulate a session for this action request
+ * to be able to pass it down for processing
+ * This is necessary to meet the previous design of manager.c
+ */
+ s.hook = hook;
+
+ ret = -1;
+ ao2_lock(act_found);
+ if (act_found->registered && act_found->func) {
+ struct ast_module *mod_ref = ast_module_running_ref(act_found->module);
+
+ ao2_unlock(act_found);
+ /* If the action is in a module it must be running. */
+ if (!act_found->module || mod_ref) {
ret = act_found->func(&s, &m);
- ao2_lock(act_found);
- if (act_found->module) {
- ast_module_unref(act_found->module);
- }
- } else {
- ret = -1;
+ ast_module_unref(mod_ref);
}
+ } else {
ao2_unlock(act_found);
- ao2_t_ref(act_found, -1, "done with found action object");
}
- }
+ ao2_t_ref(act_found, -1, "done with found action object");
+ } while (0);
+
ast_free(dup_str);
return ret;
}
@@ -6442,21 +6449,21 @@ static int process_message(struct mansession *s, const struct message *m)
if ((s->session->writeperm & act_found->authority)
|| act_found->authority == 0) {
/* We have the authority to execute the action. */
+ ret = -1;
ao2_lock(act_found);
if (act_found->registered && act_found->func) {
- ast_debug(1, "Running action '%s'\n", act_found->action);
- if (act_found->module) {
- ast_module_ref(act_found->module);
- }
+ struct ast_module *mod_ref = ast_module_running_ref(act_found->module);
+
ao2_unlock(act_found);
- ret = act_found->func(s, m);
- acted = 1;
- ao2_lock(act_found);
- if (act_found->module) {
- ast_module_unref(act_found->module);
+ if (mod_ref || !act_found->module) {
+ ast_debug(1, "Running action '%s'\n", act_found->action);
+ ret = act_found->func(s, m);
+ acted = 1;
+ ast_module_unref(mod_ref);
}
+ } else {
+ ao2_unlock(act_found);
}
- ao2_unlock(act_found);
}
if (!acted) {
/*