From: Richard Mudgett Date: Mon, 3 Dec 2012 22:53:58 +0000 (+0000) Subject: Cleanup ast_run_atexits() atexits list. X-Git-Tag: 10.12.0-rc1~15 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c4fafc9412adced0651f8a439db2d2a516efb610;p=thirdparty%2Fasterisk.git 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 git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/10@377166 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- diff --git a/main/asterisk.c b/main/asterisk.c index 379e095511..c5819613a5 100644 --- a/main/asterisk.c +++ b/main/asterisk.c @@ -212,10 +212,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; @@ -952,39 +952,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 */ @@ -1656,17 +1674,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); @@ -1749,6 +1756,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; @@ -1788,14 +1796,15 @@ static void really_quit(int num, shutdown_nice_t niceness, int restart) "Restart: %s\r\n", active_channels ? "Uncleanly" : "Cleanly", restart ? "True" : "False"); + if (option_verbose && ast_opt_console) { + ast_verbose("Asterisk %s ending (%d).\n", + active_channels ? "uncleanly" : "cleanly", num); + } if (option_verbose) ast_verbose("Executing last minute cleanups\n"); ast_run_atexits(); - /* Called on exit */ - if (option_verbose && ast_opt_console) { - ast_verbose("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);