mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-29 15:36:13 +00:00
Cleanup ast_run_atexits() atexits list.
* Convert atexits list to a mutex instead of a rd/wr lock. The lock is only write locked. * Move CLI verbose Asterisk ending message to where AMI message is output in really_quit() to avoid further surprises about using stuff already shutdown. (issue ASTERISK-20649) Reported by: Corey Farrell ........ Merged revisions 377165 from http://svn.asterisk.org/svn/asterisk/branches/1.8 ........ Merged revisions 377166 from http://svn.asterisk.org/svn/asterisk/branches/10 git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/11@377167 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -223,10 +223,10 @@ struct console {
|
|||||||
|
|
||||||
struct ast_atexit {
|
struct ast_atexit {
|
||||||
void (*func)(void);
|
void (*func)(void);
|
||||||
AST_RWLIST_ENTRY(ast_atexit) list;
|
AST_LIST_ENTRY(ast_atexit) list;
|
||||||
};
|
};
|
||||||
|
|
||||||
static AST_RWLIST_HEAD_STATIC(atexits, ast_atexit);
|
static AST_LIST_HEAD_STATIC(atexits, ast_atexit);
|
||||||
|
|
||||||
struct timeval ast_startuptime;
|
struct timeval ast_startuptime;
|
||||||
struct timeval ast_lastreloadtime;
|
struct timeval ast_lastreloadtime;
|
||||||
@@ -964,39 +964,57 @@ 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)
|
||||||
|
{
|
||||||
|
struct ast_atexit *ae;
|
||||||
|
|
||||||
|
AST_LIST_LOCK(&atexits);
|
||||||
|
while ((ae = AST_LIST_REMOVE_HEAD(&atexits, list))) {
|
||||||
|
if (ae->func) {
|
||||||
|
ae->func();
|
||||||
|
}
|
||||||
|
ast_free(ae);
|
||||||
|
}
|
||||||
|
AST_LIST_UNLOCK(&atexits);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __ast_unregister_atexit(void (*func)(void))
|
||||||
|
{
|
||||||
|
struct ast_atexit *ae;
|
||||||
|
|
||||||
|
AST_LIST_TRAVERSE_SAFE_BEGIN(&atexits, ae, list) {
|
||||||
|
if (ae->func == func) {
|
||||||
|
AST_LIST_REMOVE_CURRENT(list);
|
||||||
|
ast_free(ae);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AST_LIST_TRAVERSE_SAFE_END;
|
||||||
|
}
|
||||||
|
|
||||||
int ast_register_atexit(void (*func)(void))
|
int ast_register_atexit(void (*func)(void))
|
||||||
{
|
{
|
||||||
struct ast_atexit *ae;
|
struct ast_atexit *ae;
|
||||||
|
|
||||||
if (!(ae = ast_calloc(1, sizeof(*ae))))
|
ae = ast_calloc(1, sizeof(*ae));
|
||||||
|
if (!ae) {
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
ae->func = func;
|
ae->func = func;
|
||||||
|
|
||||||
ast_unregister_atexit(func);
|
AST_LIST_LOCK(&atexits);
|
||||||
|
__ast_unregister_atexit(func);
|
||||||
AST_RWLIST_WRLOCK(&atexits);
|
AST_LIST_INSERT_HEAD(&atexits, ae, list);
|
||||||
AST_RWLIST_INSERT_HEAD(&atexits, ae, list);
|
AST_LIST_UNLOCK(&atexits);
|
||||||
AST_RWLIST_UNLOCK(&atexits);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ast_unregister_atexit(void (*func)(void))
|
void ast_unregister_atexit(void (*func)(void))
|
||||||
{
|
{
|
||||||
struct ast_atexit *ae = NULL;
|
AST_LIST_LOCK(&atexits);
|
||||||
|
__ast_unregister_atexit(func);
|
||||||
AST_RWLIST_WRLOCK(&atexits);
|
AST_LIST_UNLOCK(&atexits);
|
||||||
AST_RWLIST_TRAVERSE_SAFE_BEGIN(&atexits, ae, list) {
|
|
||||||
if (ae->func == func) {
|
|
||||||
AST_RWLIST_REMOVE_CURRENT(list);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
AST_RWLIST_TRAVERSE_SAFE_END;
|
|
||||||
AST_RWLIST_UNLOCK(&atexits);
|
|
||||||
|
|
||||||
free(ae);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sending commands from consoles back to the daemon requires a terminating NULL */
|
/* Sending commands from consoles back to the daemon requires a terminating NULL */
|
||||||
@@ -1665,17 +1683,6 @@ int ast_set_priority(int pri)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ast_run_atexits(void)
|
|
||||||
{
|
|
||||||
struct ast_atexit *ae;
|
|
||||||
AST_RWLIST_RDLOCK(&atexits);
|
|
||||||
AST_RWLIST_TRAVERSE(&atexits, ae, list) {
|
|
||||||
if (ae->func)
|
|
||||||
ae->func();
|
|
||||||
}
|
|
||||||
AST_RWLIST_UNLOCK(&atexits);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int can_safely_quit(shutdown_nice_t niceness, int restart);
|
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);
|
||||||
|
|
||||||
@@ -1758,6 +1765,7 @@ static int can_safely_quit(shutdown_nice_t niceness, int restart)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*! Called when exiting is certain. */
|
||||||
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;
|
||||||
@@ -1816,11 +1824,12 @@ static void really_quit(int num, shutdown_nice_t niceness, int restart)
|
|||||||
"Restart: %s\r\n",
|
"Restart: %s\r\n",
|
||||||
active_channels ? "Uncleanly" : "Cleanly",
|
active_channels ? "Uncleanly" : "Cleanly",
|
||||||
restart ? "True" : "False");
|
restart ? "True" : "False");
|
||||||
|
ast_verb(0, "Asterisk %s ending (%d).\n",
|
||||||
|
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();
|
||||||
/* Called on exit */
|
|
||||||
ast_verb(0, "Asterisk %s ending (%d).\n", active_channels ? "uncleanly" : "cleanly", num);
|
|
||||||
ast_debug(1, "Asterisk ending (%d).\n", num);
|
ast_debug(1, "Asterisk ending (%d).\n", num);
|
||||||
if (ast_socket > -1) {
|
if (ast_socket > -1) {
|
||||||
pthread_cancel(lthread);
|
pthread_cancel(lthread);
|
||||||
|
|||||||
Reference in New Issue
Block a user