<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>