diff options
author | Richard Mudgett <rmudgett@digium.com> | 2012-12-03 23:00:08 +0000 |
---|---|---|
committer | Richard Mudgett <rmudgett@digium.com> | 2012-12-03 23:00:08 +0000 |
commit | 83c5fac6b1cbbd1160506c9e2d8fb8d2b4c96f42 (patch) | |
tree | 44c85736a556a7b5ff57d03a0dbd941db9fe1f06 /main/asterisk.c | |
parent | 77561124b04c8cfb56f18063f8ffe49a573e5ad0 (diff) |
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
........
Merged revisions 377167 from http://svn.asterisk.org/svn/asterisk/branches/11
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@377168 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'main/asterisk.c')
-rw-r--r-- | main/asterisk.c | 79 |
1 files changed, 44 insertions, 35 deletions
diff --git a/main/asterisk.c b/main/asterisk.c index 47ed657ad..aa12836c2 100644 --- a/main/asterisk.c +++ b/main/asterisk.c @@ -308,10 +308,10 @@ struct console { struct ast_atexit { 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_lastreloadtime; @@ -1047,39 +1047,57 @@ static char *handle_show_version_files(struct ast_cli_entry *e, int cmd, struct #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)) { struct ast_atexit *ae; - if (!(ae = ast_calloc(1, sizeof(*ae)))) + ae = ast_calloc(1, sizeof(*ae)); + if (!ae) { return -1; - + } ae->func = func; - ast_unregister_atexit(func); - - AST_RWLIST_WRLOCK(&atexits); - AST_RWLIST_INSERT_HEAD(&atexits, ae, list); - AST_RWLIST_UNLOCK(&atexits); + AST_LIST_LOCK(&atexits); + __ast_unregister_atexit(func); + AST_LIST_INSERT_HEAD(&atexits, ae, list); + AST_LIST_UNLOCK(&atexits); return 0; } void ast_unregister_atexit(void (*func)(void)) { - struct ast_atexit *ae = NULL; - - AST_RWLIST_WRLOCK(&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); + AST_LIST_LOCK(&atexits); + __ast_unregister_atexit(func); + AST_LIST_UNLOCK(&atexits); } /* Sending commands from consoles back to the daemon requires a terminating NULL */ @@ -1751,17 +1769,6 @@ int ast_set_priority(int pri) 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 void really_quit(int num, shutdown_nice_t niceness, int restart); @@ -1845,6 +1852,7 @@ static int can_safely_quit(shutdown_nice_t niceness, int restart) return 1; } +/*! Called when exiting is certain. */ static void really_quit(int num, shutdown_nice_t niceness, int restart) { int active_channels; @@ -1903,11 +1911,12 @@ static void really_quit(int num, shutdown_nice_t niceness, int restart) "Restart: %s\r\n", active_channels ? "Uncleanly" : "Cleanly", 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_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); if (ast_socket > -1) { pthread_cancel(lthread); |