mirror of
https://github.com/asterisk/asterisk.git
synced 2025-11-15 14:28:24 +00:00
main/formats: Fix crash in ast_format_cmp during non-clean shutdown.
* Backport ast_register_cleanup from Asterisk 12. * Use ast_register_cleanup for format_attr_shutdown. ast_register_cleanup was originally commited in r390122 by dlee. (closes issue ASTERISK-23103) Reported by: JoshE git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/11@411310 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -89,6 +89,22 @@ int ast_pbx_init(void); /*!< Provided by pbx.c */
|
|||||||
*/
|
*/
|
||||||
int ast_register_atexit(void (*func)(void));
|
int ast_register_atexit(void (*func)(void));
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \since 11.9
|
||||||
|
* \brief Register a function to be executed before Asterisk gracefully exits.
|
||||||
|
*
|
||||||
|
* If Asterisk is immediately shutdown (core stop now, or sending the TERM
|
||||||
|
* signal), the callback is not run. When the callbacks are run, they are run in
|
||||||
|
* sequence with ast_register_atexit() callbacks, in the reverse order of
|
||||||
|
* registration.
|
||||||
|
*
|
||||||
|
* \param func The callback function to use.
|
||||||
|
*
|
||||||
|
* \retval 0 on success.
|
||||||
|
* \retval -1 on error.
|
||||||
|
*/
|
||||||
|
int ast_register_cleanup(void (*func)(void));
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Unregister a function registered with ast_register_atexit().
|
* \brief Unregister a function registered with ast_register_atexit().
|
||||||
* \param func The callback function to unregister.
|
* \param func The callback function to unregister.
|
||||||
|
|||||||
@@ -228,6 +228,7 @@ struct console {
|
|||||||
|
|
||||||
struct ast_atexit {
|
struct ast_atexit {
|
||||||
void (*func)(void);
|
void (*func)(void);
|
||||||
|
int is_cleanup;
|
||||||
AST_LIST_ENTRY(ast_atexit) list;
|
AST_LIST_ENTRY(ast_atexit) list;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -970,13 +971,13 @@ static char *handle_show_version_files(struct ast_cli_entry *e, int cmd, struct
|
|||||||
|
|
||||||
#endif /* ! LOW_MEMORY */
|
#endif /* ! LOW_MEMORY */
|
||||||
|
|
||||||
static void ast_run_atexits(void)
|
static void ast_run_atexits(int run_cleanups)
|
||||||
{
|
{
|
||||||
struct ast_atexit *ae;
|
struct ast_atexit *ae;
|
||||||
|
|
||||||
AST_LIST_LOCK(&atexits);
|
AST_LIST_LOCK(&atexits);
|
||||||
while ((ae = AST_LIST_REMOVE_HEAD(&atexits, list))) {
|
while ((ae = AST_LIST_REMOVE_HEAD(&atexits, list))) {
|
||||||
if (ae->func) {
|
if (ae->func && (!ae->is_cleanup || run_cleanups)) {
|
||||||
ae->func();
|
ae->func();
|
||||||
}
|
}
|
||||||
ast_free(ae);
|
ast_free(ae);
|
||||||
@@ -998,7 +999,7 @@ static void __ast_unregister_atexit(void (*func)(void))
|
|||||||
AST_LIST_TRAVERSE_SAFE_END;
|
AST_LIST_TRAVERSE_SAFE_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ast_register_atexit(void (*func)(void))
|
static int register_atexit(void (*func)(void), int is_cleanup)
|
||||||
{
|
{
|
||||||
struct ast_atexit *ae;
|
struct ast_atexit *ae;
|
||||||
|
|
||||||
@@ -1007,6 +1008,7 @@ int ast_register_atexit(void (*func)(void))
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
ae->func = func;
|
ae->func = func;
|
||||||
|
ae->is_cleanup = is_cleanup;
|
||||||
|
|
||||||
AST_LIST_LOCK(&atexits);
|
AST_LIST_LOCK(&atexits);
|
||||||
__ast_unregister_atexit(func);
|
__ast_unregister_atexit(func);
|
||||||
@@ -1016,6 +1018,16 @@ int ast_register_atexit(void (*func)(void))
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ast_register_atexit(void (*func)(void))
|
||||||
|
{
|
||||||
|
return register_atexit(func, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ast_register_cleanup(void (*func)(void))
|
||||||
|
{
|
||||||
|
return register_atexit(func, 1);
|
||||||
|
}
|
||||||
|
|
||||||
void ast_unregister_atexit(void (*func)(void))
|
void ast_unregister_atexit(void (*func)(void))
|
||||||
{
|
{
|
||||||
AST_LIST_LOCK(&atexits);
|
AST_LIST_LOCK(&atexits);
|
||||||
@@ -1802,8 +1814,9 @@ static int can_safely_quit(shutdown_nice_t niceness, int restart)
|
|||||||
static void really_quit(int num, shutdown_nice_t niceness, int restart)
|
static void really_quit(int num, shutdown_nice_t niceness, int restart)
|
||||||
{
|
{
|
||||||
int active_channels;
|
int active_channels;
|
||||||
|
int run_cleanups = niceness >= SHUTDOWN_NICE;
|
||||||
|
|
||||||
if (niceness >= SHUTDOWN_NICE) {
|
if (run_cleanups) {
|
||||||
ast_module_shutdown();
|
ast_module_shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1861,7 +1874,7 @@ static void really_quit(int num, shutdown_nice_t niceness, int restart)
|
|||||||
active_channels ? "uncleanly" : "cleanly", num);
|
active_channels ? "uncleanly" : "cleanly", num);
|
||||||
|
|
||||||
ast_verb(0, "Executing last minute cleanups\n");
|
ast_verb(0, "Executing last minute cleanups\n");
|
||||||
ast_run_atexits();
|
ast_run_atexits(run_cleanups);
|
||||||
|
|
||||||
ast_debug(1, "Asterisk ending (%d).\n", num);
|
ast_debug(1, "Asterisk ending (%d).\n", num);
|
||||||
if (ast_socket > -1) {
|
if (ast_socket > -1) {
|
||||||
|
|||||||
@@ -1128,7 +1128,7 @@ int ast_format_attr_init(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ast_cli_register_multiple(my_clis, ARRAY_LEN(my_clis));
|
ast_cli_register_multiple(my_clis, ARRAY_LEN(my_clis));
|
||||||
ast_register_atexit(format_attr_shutdown);
|
ast_register_cleanup(format_attr_shutdown);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user