summaryrefslogtreecommitdiff
path: root/include/asterisk/manager.h
diff options
context:
space:
mode:
authorRichard Mudgett <rmudgett@digium.com>2012-03-20 17:31:28 +0000
committerRichard Mudgett <rmudgett@digium.com>2012-03-20 17:31:28 +0000
commit334f13d8b8ea94f388af20c144f24097089e5e1c (patch)
tree61918aebd949a7f4675e79e847e91d7bc4414477 /include/asterisk/manager.h
parent3714e8b1e528fd3d19ac169ef689160f4bfad2eb (diff)
Allow AMI action callback to be reentrant.
Fix AMI module reload deadlock regression from ASTERISK-18479 when it tried to fix the race between calling an AMI action callback and unregistering that action. Refixes ASTERISK-13784 broken by ASTERISK-17785 change. Locking the ao2 object guaranteed that there were no active callbacks that mattered when ast_manager_unregister() was called. Unfortunately, this causes the deadlock situation. The patch stops locking the ao2 object to allow multiple threads to invoke the callback re-entrantly. There is no way to guarantee a module unload will not crash because of an active callback. The code attempts to minimize the chance with the registered flag and the maximum 5 second delay before ast_manager_unregister() returns. The trunk version of the patch changes the API to fix the race condition correctly to prevent the module code from unloading from memory while an action callback is active. * Don't hold the lock while calling the AMI action callback. (closes issue ASTERISK-19487) Reported by: Philippe Lindheimer Review: https://reviewboard.asterisk.org/r/1818/ Review: https://reviewboard.asterisk.org/r/1820/ ........ Merged revisions 359979 from http://svn.asterisk.org/svn/asterisk/branches/1.8 ........ Merged revisions 359980 from http://svn.asterisk.org/svn/asterisk/branches/10 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@359981 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'include/asterisk/manager.h')
-rw-r--r--include/asterisk/manager.h44
1 files changed, 30 insertions, 14 deletions
diff --git a/include/asterisk/manager.h b/include/asterisk/manager.h
index 534e43f90..36b03a9fc 100644
--- a/include/asterisk/manager.h
+++ b/include/asterisk/manager.h
@@ -149,6 +149,7 @@ struct manager_action {
int authority;
/*! Function to be called */
int (*func)(struct mansession *s, const struct message *m);
+ struct ast_module *module; /*!< Module this action belongs to */
/*! Where the documentation come from. */
enum ast_doc_src docsrc;
/*! For easy linking */
@@ -164,29 +165,44 @@ struct manager_action {
/*! \brief External routines may register/unregister manager callbacks this way
* \note Use ast_manager_register2() to register with help text for new manager commands */
-#define ast_manager_register(a, b, c, d) ast_manager_register2(a, b, c, d, NULL)
+#define ast_manager_register(action, authority, func, synopsis) ast_manager_register2(action, authority, func, ast_module_info->self, synopsis, NULL)
/*! \brief Register a manager callback using XML documentation to describe the manager. */
-#define ast_manager_register_xml(a, b, c) ast_manager_register2(a, b, c, NULL, NULL)
-
-/*! \brief Register a manager command with the manager interface
- \param action Name of the requested Action:
- \param authority Required authority for this command
- \param func Function to call for this command
- \param synopsis Help text (one line, up to 30 chars) for CLI manager show commands
- \param description Help text, several lines
-*/
+#define ast_manager_register_xml(action, authority, func) ast_manager_register2(action, authority, func, ast_module_info->self, NULL, NULL)
+
+/*!
+ * \brief Register a manager callback using XML documentation to describe the manager.
+ *
+ * \note For Asterisk core modules that are not independently
+ * loadable.
+ *
+ * \warning If you use ast_manager_register_xml() instead when
+ * you need to use this function, Asterisk will crash on load.
+ */
+#define ast_manager_register_xml_core(action, authority, func) ast_manager_register2(action, authority, func, NULL, NULL, NULL)
+
+/*!
+ * \brief Register a manager command with the manager interface
+ * \param action Name of the requested Action:
+ * \param authority Required authority for this command
+ * \param func Function to call for this command
+ * \param module The module containing func. (NULL if module is part of core and not loadable)
+ * \param synopsis Help text (one line, up to 30 chars) for CLI manager show commands
+ * \param description Help text, several lines
+ */
int ast_manager_register2(
const char *action,
int authority,
int (*func)(struct mansession *s, const struct message *m),
+ struct ast_module *module,
const char *synopsis,
const char *description);
-/*! \brief Unregister a registered manager command
- \param action Name of registered Action:
-*/
-int ast_manager_unregister( char *action );
+/*!
+ * \brief Unregister a registered manager command
+ * \param action Name of registered Action:
+ */
+int ast_manager_unregister(const char *action);
/*!
* \brief Verify a session's read permissions against a permission mask.