<p>Richard Mudgett has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/6763">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">cdr.c: Defer getting ao2_global_obj_ref() until needed.<br><br>The CDR performance gets worse the further it gets behind in processing<br>stasis messages.  One of the reasons is we were getting the global config<br>even if we didn't need it.<br><br>* Most uses of the global config were only needed on off nominal code<br>paths so it makes sense to not get it until absolutely needed.<br><br>ASTERISK-27335<br><br>Change-Id: I00c63b7ec233e5bfffd5d976f05568613d3c2365<br>---<br>M main/cdr.c<br>1 file changed, 46 insertions(+), 30 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/63/6763/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">diff --git a/main/cdr.c b/main/cdr.c<br>index 1481ae7..19c8200 100644<br>--- a/main/cdr.c<br>+++ b/main/cdr.c<br>@@ -950,6 +950,27 @@<br> }<br> <br> /*!<br>+ * \internal<br>+ * \brief Determine if CDR_END_BEFORE_H_EXTEN is configured.<br>+ *<br>+ * \retval 0 if CDR_END_BEFORE_H_EXTEN not configured.<br>+ * \retval non-zero if CDR_END_BEFORE_H_EXTEN is configured.<br>+ *<br>+ * \return Nothing<br>+ */<br>+static int is_end_before_h_exten_set(void)<br>+{<br>+    struct module_config *mod_cfg;<br>+       int end_before_h_exten;<br>+<br>+   mod_cfg = ao2_global_obj_ref(module_configs);<br>+        end_before_h_exten = !mod_cfg<br>+                || ast_test_flag(&mod_cfg->general->settings, CDR_END_BEFORE_H_EXTEN);<br>+     ao2_cleanup(mod_cfg);<br>+        return end_before_h_exten;<br>+}<br>+<br>+/*!<br>  * \brief Return whether or not a channel has changed its state in the dialplan, subject<br>  * to endbeforehexten logic<br>  *<br>@@ -962,12 +983,9 @@<br> static int snapshot_cep_changed(struct ast_channel_snapshot *old_snapshot,<br>      struct ast_channel_snapshot *new_snapshot)<br> {<br>-       RAII_VAR(struct module_config *, mod_cfg,<br>-            ao2_global_obj_ref(module_configs), ao2_cleanup);<br>-<br>  /* If we ignore hangup logic, don't indicate that we're executing anything new */<br>-    if (ast_test_flag(&mod_cfg->general->settings, CDR_END_BEFORE_H_EXTEN)<br>-             && ast_test_flag(&new_snapshot->softhangup_flags, AST_SOFTHANGUP_HANGUP_EXEC)) {<br>+      if (ast_test_flag(&new_snapshot->softhangup_flags, AST_SOFTHANGUP_HANGUP_EXEC)<br>+                && is_end_before_h_exten_set()) {<br>             return 0;<br>     }<br> <br>@@ -975,10 +993,11 @@<br>    * will attempt to clear the application and restore the dummy originate application<br>   * of "AppDialX". Ignore application changes to AppDialX as a result.<br>        */<br>-  if (strcmp(new_snapshot->appl, old_snapshot->appl) && strncasecmp(new_snapshot->appl, "appdial", 7)<br>+       if (strcmp(new_snapshot->appl, old_snapshot->appl)<br>+             && strncasecmp(new_snapshot->appl, "appdial", 7)<br>                 && (strcmp(new_snapshot->context, old_snapshot->context)<br>-               || strcmp(new_snapshot->exten, old_snapshot->exten)<br>-            || new_snapshot->priority != old_snapshot->priority)) {<br>+                        || strcmp(new_snapshot->exten, old_snapshot->exten)<br>+                    || new_snapshot->priority != old_snapshot->priority)) {<br>                 return 1;<br>     }<br> <br>@@ -1219,8 +1238,7 @@<br>  */<br> static void cdr_object_set_disposition(struct cdr_object *cdr, int hangupcause)<br> {<br>-      RAII_VAR(struct module_config *, mod_cfg,<br>-                    ao2_global_obj_ref(module_configs), ao2_cleanup);<br>+    struct module_config *mod_cfg;<br> <br>     /* Change the disposition based on the hang up cause */<br>       switch (hangupcause) {<br>@@ -1228,11 +1246,14 @@<br>               cdr->disposition = AST_CDR_BUSY;<br>           break;<br>        case AST_CAUSE_CONGESTION:<br>-           if (!ast_test_flag(&mod_cfg->general->settings, CDR_CONGESTION)) {<br>+         mod_cfg = ao2_global_obj_ref(module_configs);<br>+                if (!mod_cfg<br>+                 || !ast_test_flag(&mod_cfg->general->settings, CDR_CONGESTION)) {<br>                   cdr->disposition = AST_CDR_FAILED;<br>                 } else {<br>                      cdr->disposition = AST_CDR_CONGESTION;<br>             }<br>+            ao2_cleanup(mod_cfg);<br>                 break;<br>        case AST_CAUSE_NO_ROUTE_DESTINATION:<br>  case AST_CAUSE_UNREGISTERED:<br>@@ -1295,10 +1316,8 @@<br>  */<br> static void cdr_object_check_party_a_hangup(struct cdr_object *cdr)<br> {<br>- RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);<br>-<br>-       if (ast_test_flag(&mod_cfg->general->settings, CDR_END_BEFORE_H_EXTEN)<br>-             && ast_test_flag(&cdr->party_a.snapshot->softhangup_flags, AST_SOFTHANGUP_HANGUP_EXEC)) {<br>+  if (ast_test_flag(&cdr->party_a.snapshot->softhangup_flags, AST_SOFTHANGUP_HANGUP_EXEC)<br>+            && is_end_before_h_exten_set()) {<br>             cdr_object_finalize(cdr);<br>     }<br> <br>@@ -1361,13 +1380,11 @@<br> <br> static int base_process_party_a(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot)<br> {<br>-        RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup);<br>-<br>        ast_assert(strcasecmp(snapshot->name, cdr->party_a.snapshot->name) == 0);<br> <br>         /* Finalize the CDR if we're in hangup logic and we're set to do so */<br>        if (ast_test_flag(&snapshot->softhangup_flags, AST_SOFTHANGUP_HANGUP_EXEC)<br>-            && ast_test_flag(&mod_cfg->general->settings, CDR_END_BEFORE_H_EXTEN)) {<br>+           && is_end_before_h_exten_set()) {<br>             cdr_object_finalize(cdr);<br>             return 0;<br>     }<br>@@ -1655,9 +1672,6 @@<br>  */<br> static enum ast_cdr_disposition dial_status_to_disposition(const char *dial_status)<br> {<br>-     RAII_VAR(struct module_config *, mod_cfg,<br>-            ao2_global_obj_ref(module_configs), ao2_cleanup);<br>-<br>  if (!strcmp(dial_status, "ANSWER")) {<br>               return AST_CDR_ANSWERED;<br>      } else if (!strcmp(dial_status, "BUSY")) {<br>@@ -1665,7 +1679,15 @@<br>  } else if (!strcmp(dial_status, "CANCEL") || !strcmp(dial_status, "NOANSWER")) {<br>          return AST_CDR_NOANSWER;<br>      } else if (!strcmp(dial_status, "CONGESTION")) {<br>-           if (!ast_test_flag(&mod_cfg->general->settings, CDR_CONGESTION)) {<br>+         struct module_config *mod_cfg;<br>+               int is_congestion;<br>+<br>+                mod_cfg = ao2_global_obj_ref(module_configs);<br>+                is_congestion = mod_cfg<br>+                      && ast_test_flag(&mod_cfg->general->settings, CDR_CONGESTION);<br>+             ao2_cleanup(mod_cfg);<br>+<br>+             if (!is_congestion) {<br>                         return AST_CDR_FAILED;<br>                } else {<br>                      return AST_CDR_CONGESTION;<br>@@ -1875,11 +1897,8 @@<br> <br> static int finalized_state_process_party_a(struct cdr_object *cdr, struct ast_channel_snapshot *snapshot)<br> {<br>-        RAII_VAR(struct module_config *, mod_cfg,<br>-            ao2_global_obj_ref(module_configs), ao2_cleanup);<br>-<br>  if (ast_test_flag(&snapshot->softhangup_flags, AST_SOFTHANGUP_HANGUP_EXEC)<br>-                    && ast_test_flag(&mod_cfg->general->settings, CDR_END_BEFORE_H_EXTEN)) {<br>+           && is_end_before_h_exten_set()) {<br>             return 0;<br>     }<br> <br>@@ -2051,13 +2070,10 @@<br> static int check_new_cdr_needed(struct ast_channel_snapshot *old_snapshot,<br>            struct ast_channel_snapshot *new_snapshot)<br> {<br>-       RAII_VAR(struct module_config *, mod_cfg,<br>-                    ao2_global_obj_ref(module_configs), ao2_cleanup);<br>-<br>  /* If we're dead, we don't need a new CDR */<br>  if (!new_snapshot<br>             || (ast_test_flag(&new_snapshot->softhangup_flags, AST_SOFTHANGUP_HANGUP_EXEC)<br>-                        && ast_test_flag(&mod_cfg->general->settings, CDR_END_BEFORE_H_EXTEN))) {<br>+                  && is_end_before_h_exten_set())) {<br>            return 0;<br>     }<br> <br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/6763">change 6763</a>. To unsubscribe, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/6763"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 13 </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I00c63b7ec233e5bfffd5d976f05568613d3c2365 </div>
<div style="display:none"> Gerrit-Change-Number: 6763 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Richard Mudgett <rmudgett@digium.com> </div>