<p>Corey Farrell has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/7987">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">loader: Rework load_resource_list.<br><br>Use a single loop in a loop to scan the resource list attempting to<br>dlopen each module.  The inner loop is repeated until it doesn't do any<br>work, then it is run one more time to allow printing of error messages.<br><br>Change-Id: I60c15cd57ff9680b62e2a94c7519401fa4a38e45<br>---<br>M main/loader.c<br>1 file changed, 30 insertions(+), 63 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/87/7987/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">diff --git a/main/loader.c b/main/loader.c<br>index 62a97fc..14de8cd 100644<br>--- a/main/loader.c<br>+++ b/main/loader.c<br>@@ -1635,13 +1635,12 @@<br> {<br>   struct module_vector resource_heap;<br>   struct load_order_entry *order;<br>-      struct load_retries load_retries;<br>+    int attempt = 0;<br>      int count = 0;<br>        int res = 0;<br>- int i = 0;<br>+   int didwork;<br>+ int lasttry = 0;<br> #define LOAD_RETRIES 4<br>-<br>- AST_LIST_HEAD_INIT_NOLOCK(&load_retries);<br> <br>      if (AST_VECTOR_INIT(&resource_heap, 500)) {<br>               ast_log(LOG_ERROR, "Failed to initialize module loader.\n");<br>@@ -1649,91 +1648,59 @@<br>               return -1;<br>    }<br> <br>- /* first, add find and add modules to heap */<br>-        AST_LIST_TRAVERSE_SAFE_BEGIN(load_order, order, entry) {<br>-             enum ast_module_load_result lres;<br>+    while (!res) {<br>+               didwork = 0;<br> <br>-              /* Suppress log messages unless this is the last pass */<br>-             lres = load_resource(order->resource, 1, &resource_heap, order->required);<br>-         ast_debug(3, "PASS 0: %-46s %d\n", order->resource, lres);<br>-              switch (lres) {<br>-              case AST_MODULE_LOAD_SUCCESS:<br>-                        /* We're supplying a heap so SUCCESS isn't possible but we still have to test for it. */<br>-                     break;<br>-               case AST_MODULE_LOAD_FAILURE:<br>-                case AST_MODULE_LOAD_DECLINE:<br>-                        /*<br>-                    * DECLINE or FAILURE means there was an issue with dlopen or module_register<br>-                         * which might be retryable.  LOAD_FAILURE only happens for required modules<br>-                  * but we're still going to retry.  We need to remove the entry from the<br>-                  * load_order list and add it to the load_retries list.<br>-                       */<br>-                  AST_LIST_REMOVE_CURRENT(entry);<br>-                      AST_LIST_INSERT_TAIL(&load_retries, order, entry);<br>-                       break;<br>-               case AST_MODULE_LOAD_SKIP:<br>-                   /*<br>-                    * SKIP means that dlopen worked but global_symbols was set and this module doesn't qualify.<br>-                      * Leave it in load_order for the next call of load_resource_list.<br>-                    */<br>-                  break;<br>-               case AST_MODULE_LOAD_PRIORITY:<br>-                       /* load_resource worked and the module was added to the priority vector */<br>-                   AST_LIST_REMOVE_CURRENT(entry);<br>-                      ast_free(order->resource);<br>-                        ast_free(order);<br>-                     break;<br>-               }<br>-    }<br>-    AST_LIST_TRAVERSE_SAFE_END;<br>-<br>-       /* Retry the failures until the list is empty or we reach LOAD_RETRIES */<br>-    for (i = 0; !AST_LIST_EMPTY(&load_retries) && i < LOAD_RETRIES; i++) {<br>-                AST_LIST_TRAVERSE_SAFE_BEGIN(&load_retries, order, entry) {<br>+              AST_LIST_TRAVERSE_SAFE_BEGIN(load_order, order, entry) {<br>                      enum ast_module_load_result lres;<br> <br>                  /* Suppress log messages unless this is the last pass */<br>-                     lres = load_resource(order->resource, (i < LOAD_RETRIES - 1), &resource_heap, order->required);<br>-                 ast_debug(3, "PASS %d %-46s %d\n", i + 1, order->resource, lres);<br>+                       lres = load_resource(order->resource, !lasttry, &resource_heap, order->required);<br>+                  ast_debug(3, "PASS %d: %-46s %d\n", attempt, order->resource, lres);<br>                     switch (lres) {<br>-                      /* These are all retryable. */<br>                        case AST_MODULE_LOAD_SUCCESS:<br>+                        case AST_MODULE_LOAD_SKIP:<br>+                           /* We're supplying a heap so SUCCESS isn't possible but we still have to test for it.<br>+                                 * SKIP is only used when we try to start a module that is missing dependencies. */<br>+                          break;<br>                        case AST_MODULE_LOAD_DECLINE:<br>                                 break;<br>                        case AST_MODULE_LOAD_FAILURE:<br>                                 /* LOAD_FAILURE only happens for required modules */<br>-                         if (i == LOAD_RETRIES - 1) {<br>-                                 /* This was the last chance to load a required module*/<br>+                              if (lasttry) {<br>+                                       /* This run is just to print errors. */<br>                                       ast_log(LOG_ERROR, "*** Failed to load module %s - Required\n", order->resource);<br>                                        fprintf(stderr, "*** Failed to load module %s - Required\n", order->resource);<br>                                   res =  -2;<br>-                                   goto done;<br>                            }<br>-                            break;;<br>-                      case AST_MODULE_LOAD_SKIP:<br>-                           /*<br>-                            * SKIP means that dlopen worked but global_symbols was set and this module<br>-                           * doesn't qualify.  Put it back in load_order for the next call of<br>-                               * load_resource_list.<br>-                                */<br>-                          AST_LIST_REMOVE_CURRENT(entry);<br>-                              AST_LIST_INSERT_TAIL(load_order, order, entry);<br>                               break;<br>                        case AST_MODULE_LOAD_PRIORITY:<br>-                               /* load_resource worked and the module was added to the priority heap */<br>+                             /* load_resource worked and the module was added to the priority vector */<br>                            AST_LIST_REMOVE_CURRENT(entry);<br>                               ast_free(order->resource);<br>                                 ast_free(order);<br>+                             didwork = 1;<br>                          break;<br>                        }<br>             }<br>             AST_LIST_TRAVERSE_SAFE_END;<br>+<br>+               if (!didwork) {<br>+                      if (lasttry) {<br>+                               break;<br>+                       }<br>+                    /* We know the next try is going to fail, it's only being performed<br>+                       * so we can print errors. */<br>+                        lasttry = 1;<br>+         }<br>+            attempt++;<br>    }<br> <br>- res = start_resource_list(&resource_heap, &count);<br>+   if (!res) {<br>+          res = start_resource_list(&resource_heap, &count);<br>+   }<br> <br>-done:<br>- while ((order = AST_LIST_REMOVE_HEAD(&load_retries, entry))) {<br>+   while ((order = AST_LIST_REMOVE_HEAD(load_order, entry))) {<br>           ast_free(order->resource);<br>                 ast_free(order);<br>      }<br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/7987">change 7987</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/7987"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I60c15cd57ff9680b62e2a94c7519401fa4a38e45 </div>
<div style="display:none"> Gerrit-Change-Number: 7987 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Corey Farrell <git@cfware.com> </div>