]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Merged revisions 377070,377074 via svnmerge from
authorAutomerge script <automerge@asterisk.org>
Mon, 3 Dec 2012 19:25:40 +0000 (19:25 +0000)
committerAutomerge script <automerge@asterisk.org>
Mon, 3 Dec 2012 19:25:40 +0000 (19:25 +0000)
file:///srv/subversion/repos/asterisk/branches/10

................
  r377070 | rmudgett | 2012-12-03 12:41:28 -0600 (Mon, 03 Dec 2012) | 15 lines

  Cleanup CDR resources on exit.

  * Simplify do_reload() return handling since it never returned anything
  other than 0.

  (issue ASTERISK-20649)
  Reported by: Corey Farrell
  Patches:
        cdr-cleanup-1_8.patch (license #5909) patch uploaded by Corey Farrell
        cdr-cleanup-10-11-trunk.patch (license #5909) patch uploaded by Corey Farrell
        Modified
  ........

  Merged revisions 377069 from http://svn.asterisk.org/svn/asterisk/branches/1.8
................
  r377074 | rmudgett | 2012-12-03 13:14:14 -0600 (Mon, 03 Dec 2012) | 12 lines

  Cleanup CLI resources on exit and CLI command registration errors.

  (issue ASTERISK-20649)
  Reported by: Corey Farrell
  Patches:
        cli-leaks-1_8-10.patch (license #5909) patch uploaded by Corey Farrell
        cli-leaks-11-trunk.patch (license #5909) patch uploaded by Corey Farrell
        Modified
  ........

  Merged revisions 377073 from http://svn.asterisk.org/svn/asterisk/branches/1.8
................

git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/10-digiumphones@377103 65c4cc65-6c06-0410-ace0-fbb531ad65f3

main/cdr.c
main/cli.c

index 97d13f933cb230109aa41a76cb5082ec093d678a..34d41412a9e42d64da5bd5a4fdcb3f0d9a5033f1 100644 (file)
@@ -1481,7 +1481,7 @@ static char *handle_cli_submit(struct ast_cli_entry *e, int cmd, struct ast_cli_
 static struct ast_cli_entry cli_submit = AST_CLI_DEFINE(handle_cli_submit, "Posts all pending batched CDR data");
 static struct ast_cli_entry cli_status = AST_CLI_DEFINE(handle_cli_status, "Display the CDR status");
 
-static int do_reload(int reload)
+static void do_reload(int reload)
 {
        struct ast_config *config;
        const char *enabled_value;
@@ -1497,11 +1497,10 @@ static int do_reload(int reload)
        int cfg_time;
        int was_enabled;
        int was_batchmode;
-       int res=0;
        struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
 
        if ((config = ast_config_load2("cdr.conf", "cdr", config_flags)) == CONFIG_STATUS_FILEUNCHANGED) {
-               return 0;
+               return;
        }
 
        ast_mutex_lock(&cdr_batch_lock);
@@ -1519,7 +1518,7 @@ static int do_reload(int reload)
 
        if (config == CONFIG_STATUS_FILEMISSING || config == CONFIG_STATUS_FILEINVALID) {
                ast_mutex_unlock(&cdr_batch_lock);
-               return 0;
+               return;
        }
 
        /* don't run the next scheduled CDR posting while reloading */
@@ -1582,7 +1581,6 @@ static int do_reload(int reload)
                } else {
                        ast_cli_register(&cli_submit);
                        ast_register_atexit(ast_cdr_engine_term);
-                       res = 0;
                }
        /* if this reload disabled the CDR and/or batch mode and there is a background thread,
           kill it */
@@ -1595,27 +1593,39 @@ static int do_reload(int reload)
                ast_cond_destroy(&cdr_pending_cond);
                ast_cli_unregister(&cli_submit);
                ast_unregister_atexit(ast_cdr_engine_term);
-               res = 0;
                /* if leaving batch mode, then post the CDRs in the batch,
                   and don't reschedule, since we are stopping CDR logging */
                if (!batchmode && was_batchmode) {
                        ast_cdr_engine_term();
                }
-       } else {
-               res = 0;
        }
 
        ast_mutex_unlock(&cdr_batch_lock);
        ast_config_destroy(config);
        manager_event(EVENT_FLAG_SYSTEM, "Reload", "Module: CDR\r\nMessage: CDR subsystem reload requested\r\n");
+}
 
-       return res;
+static void cdr_engine_shutdown(void)
+{
+       if (cdr_thread != AST_PTHREADT_NULL) {
+               /* wake up the thread so it will exit */
+               pthread_cancel(cdr_thread);
+               pthread_kill(cdr_thread, SIGURG);
+               pthread_join(cdr_thread, NULL);
+               cdr_thread = AST_PTHREADT_NULL;
+               ast_cond_destroy(&cdr_pending_cond);
+       }
+       ast_cli_unregister(&cli_submit);
+
+       ast_cli_unregister(&cli_status);
+       ast_sched_context_destroy(sched);
+       sched = NULL;
+       ast_free(batch);
+       batch = NULL;
 }
 
 int ast_cdr_engine_init(void)
 {
-       int res;
-
        sched = ast_sched_context_create();
        if (!sched) {
                ast_log(LOG_ERROR, "Unable to create schedule context.\n");
@@ -1623,15 +1633,10 @@ int ast_cdr_engine_init(void)
        }
 
        ast_cli_register(&cli_status);
+       do_reload(0);
+       ast_register_atexit(cdr_engine_shutdown);
 
-       res = do_reload(0);
-       if (res) {
-               ast_mutex_lock(&cdr_batch_lock);
-               res = init_batch();
-               ast_mutex_unlock(&cdr_batch_lock);
-       }
-
-       return res;
+       return 0;
 }
 
 /* \note This actually gets called a couple of times at shutdown.  Once, before we start
@@ -1643,7 +1648,8 @@ void ast_cdr_engine_term(void)
 
 int ast_cdr_engine_reload(void)
 {
-       return do_reload(1);
+       do_reload(1);
+       return 0;
 }
 
 int ast_cdr_data_add_structure(struct ast_data *tree, struct ast_cdr *cdr, int recur)
index e227f99ff55e35ac0b989314582429c053c6aad8..b96c799e175f97231561443d98536c10670b77e6 100644 (file)
@@ -1871,10 +1871,16 @@ int ast_cli_perms_init(int reload)
        return 0;
 }
 
+static void cli_shutdown(void)
+{
+       ast_cli_unregister_multiple(cli_cli, ARRAY_LEN(cli_cli));
+}
+
 /*! \brief initialize the _full_cmd string in * each of the builtins. */
 void ast_builtins_init(void)
 {
        ast_cli_register_multiple(cli_cli, ARRAY_LEN(cli_cli));
+       ast_register_atexit(cli_shutdown);
 }
 
 /*!
@@ -2039,6 +2045,18 @@ static char *find_best(const char *argv[])
        return cmdline;
 }
 
+static int cli_is_registered(struct ast_cli_entry *e)
+{
+       struct ast_cli_entry *cur = NULL;
+
+       while ((cur = cli_next(cur))) {
+               if (cur == e) {
+                       return 1;
+               }
+       }
+       return 0;
+}
+
 static int __ast_cli_unregister(struct ast_cli_entry *e, struct ast_cli_entry *ed)
 {
        if (e->inuse) {
@@ -2070,6 +2088,15 @@ static int __ast_cli_register(struct ast_cli_entry *e, struct ast_cli_entry *ed)
        char **dst = (char **)e->cmda;  /* need to cast as the entry is readonly */
        char *s;
 
+       AST_RWLIST_WRLOCK(&helpers);
+
+       if (cli_is_registered(e)) {
+               ast_log(LOG_WARNING, "Command '%s' already registered (the same ast_cli_entry)\n",
+                       S_OR(e->_full_cmd, e->command));
+               ret = 0;  /* report success */
+               goto done;
+       }
+
        memset(&a, '\0', sizeof(a));
        e->handler(e, CLI_INIT, &a);
        /* XXX check that usage and command are filled up */
@@ -2084,15 +2111,17 @@ static int __ast_cli_register(struct ast_cli_entry *e, struct ast_cli_entry *ed)
                s = ast_skip_blanks(s);
        }
        *dst++ = NULL;
-       
-       AST_RWLIST_WRLOCK(&helpers);
-       
+
        if (find_cli(e->cmda, 1)) {
-               ast_log(LOG_WARNING, "Command '%s' already registered (or something close enough)\n", S_OR(e->_full_cmd, e->command));
+               ast_log(LOG_WARNING, "Command '%s' already registered (or something close enough)\n",
+                       S_OR(e->_full_cmd, e->command));
                goto done;
        }
-       if (set_full_cmd(e))
+       if (set_full_cmd(e)) {
+               ast_log(LOG_WARNING, "Error registering CLI Command '%s'\n",
+                       S_OR(e->_full_cmd, e->command));
                goto done;
+       }
 
        lf = e->cmdlen;
        AST_RWLIST_TRAVERSE_SAFE_BEGIN(&helpers, cur, list) {
@@ -2112,6 +2141,10 @@ static int __ast_cli_register(struct ast_cli_entry *e, struct ast_cli_entry *ed)
 
 done:
        AST_RWLIST_UNLOCK(&helpers);
+       if (ret) {
+               ast_free(e->command);
+               e->command = NULL;
+       }
 
        return ret;
 }