]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Cleanup ast_run_atexits() atexits list.
authorRichard Mudgett <rmudgett@digium.com>
Mon, 3 Dec 2012 22:53:58 +0000 (22:53 +0000)
committerRichard Mudgett <rmudgett@digium.com>
Mon, 3 Dec 2012 22:53:58 +0000 (22:53 +0000)
* 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

main/asterisk.c

index 379e095511d134c7481b0681d910dab84c8d31f1..c5819613a520d741fc389950be4791c750fad1ac 100644 (file)
@@ -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);