summaryrefslogtreecommitdiff
path: root/main/asterisk.c
diff options
context:
space:
mode:
authorRichard Mudgett <rmudgett@digium.com>2012-12-03 23:00:08 +0000
committerRichard Mudgett <rmudgett@digium.com>2012-12-03 23:00:08 +0000
commit83c5fac6b1cbbd1160506c9e2d8fb8d2b4c96f42 (patch)
tree44c85736a556a7b5ff57d03a0dbd941db9fe1f06 /main/asterisk.c
parent77561124b04c8cfb56f18063f8ffe49a573e5ad0 (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.c79
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);