Release AMI connections on shutdown.
authorCorey Farrell <git@cfware.com>
Sun, 5 Oct 2014 00:49:45 +0000 (00:49 +0000)
committerCorey Farrell <git@cfware.com>
Sun, 5 Oct 2014 00:49:45 +0000 (00:49 +0000)
ASTERISK-24378 #close
Reported by: Corey Farrell
Review: https://reviewboard.asterisk.org/r/4037/
........

Merged revisions 424578 from http://svn.asterisk.org/svn/asterisk/branches/11
........

Merged revisions 424579 from http://svn.asterisk.org/svn/asterisk/branches/12
........

Merged revisions 424580 from http://svn.asterisk.org/svn/asterisk/branches/13

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@424581 65c4cc65-6c06-0410-ace0-fbb531ad65f3

main/manager.c

index c4ab272..1bf1f3c 100644 (file)
@@ -1261,6 +1261,9 @@ struct stasis_subscription *test_suite_sub;
 
 #define MAX_VARS 128
 
+/*! \brief Fake event class used to end sessions at shutdown */
+#define EVENT_FLAG_SHUTDOWN -1
+
 /*! \brief
  * Descriptor for a manager session, either on the AMI socket or over HTTP.
  *
@@ -5401,6 +5404,10 @@ static int process_events(struct mansession *s)
                struct eventqent *eqe = s->session->last_ev;
 
                while ((eqe = advance_event(eqe))) {
+                       if (eqe->category == EVENT_FLAG_SHUTDOWN) {
+                               ast_debug(3, "Received CloseSession event\n");
+                               ret = -1;
+                       }
                        if (!ret && s->session->authenticated &&
                            (s->session->readperm & eqe->category) == eqe->category &&
                            (s->session->send_events & eqe->category) == eqe->category) {
@@ -6331,7 +6338,7 @@ int __ast_manager_event_multichan(int category, const char *event, int chancount
                ao2_iterator_destroy(&i);
        }
 
-       if (!AST_RWLIST_EMPTY(&manager_hooks)) {
+       if (category != EVENT_FLAG_SHUTDOWN && !AST_RWLIST_EMPTY(&manager_hooks)) {
                AST_RWLIST_RDLOCK(&manager_hooks);
                AST_RWLIST_TRAVERSE(&manager_hooks, hook, list) {
                        hook->helper(category, event, ast_str_buffer(buf));
@@ -8114,6 +8121,9 @@ static void manager_shutdown(void)
 {
        struct ast_manager_user *user;
 
+       /* This event is not actually transmitted, but causes all TCP sessions to be closed */
+       manager_event(EVENT_FLAG_SHUTDOWN, "CloseSession", "CloseSession: true\r\n");
+
        ast_manager_unregister("Ping");
        ast_manager_unregister("Events");
        ast_manager_unregister("Logoff");