<p>George Joseph <strong>merged</strong> this change.</p><p><a href="https://gerrit.asterisk.org/7605">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Richard Mudgett: Looks good to me, but someone else must approve
  George Joseph: Looks good to me, approved
  Jenkins2: Approved for Submit

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">loader: Replace priority heap with vector.<br><br>This is needed for future changes which will require being able to<br>process the load priority out of order.<br><br>Change-Id: Ia23421197f09789940510b03ebbbf3bf24d51bea<br>---<br>M include/asterisk/module.h<br>M main/loader.c<br>2 files changed, 47 insertions(+), 40 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">diff --git a/include/asterisk/module.h b/include/asterisk/module.h<br>index b9d7de6..66de5c6 100644<br>--- a/include/asterisk/module.h<br>+++ b/include/asterisk/module.h<br>@@ -69,7 +69,7 @@<br>        AST_MODULE_LOAD_SUCCESS = 0,    /*!< Module loaded and configured */<br>       AST_MODULE_LOAD_DECLINE = 1,    /*!< Module is not configured */<br>   AST_MODULE_LOAD_SKIP = 2,       /*!< Module was skipped for some reason (For loader.c use only. Should never be returned by modules)*/<br>-    AST_MODULE_LOAD_PRIORITY = 3,   /*!< Module is not loaded yet, but is added to prioity heap */<br>+    AST_MODULE_LOAD_PRIORITY = 3,   /*!< Module is not loaded yet, but is added to priority list */<br>    AST_MODULE_LOAD_FAILURE = -1,   /*!< Module could not be loaded properly */<br> };<br> <br>diff --git a/main/loader.c b/main/loader.c<br>index 4d77555..7cba97f 100644<br>--- a/main/loader.c<br>+++ b/main/loader.c<br>@@ -54,7 +54,7 @@<br> #include "asterisk/features_config.h"<br> #include "asterisk/dsp.h"<br> #include "asterisk/udptl.h"<br>-#include "asterisk/heap.h"<br>+#include "asterisk/vector.h"<br> #include "asterisk/app.h"<br> #include "asterisk/test.h"<br> #include "asterisk/sounds_index.h"<br>@@ -112,6 +112,8 @@<br> <br> static char buildopt_sum[33] = AST_BUILDOPT_SUM;<br> <br>+AST_VECTOR(module_vector, struct ast_module *);<br>+<br> /*!<br>  * \brief Internal flag to indicate all modules have been initially loaded.<br>  */<br>@@ -143,6 +145,23 @@<br> };<br> <br> static AST_DLLIST_HEAD_STATIC(module_list, ast_module);<br>+<br>+static int module_vector_cmp(struct ast_module *a, struct ast_module *b)<br>+{<br>+    /* if load_pri is not set, default is 128.  Lower is better */<br>+       int a_pri = ast_test_flag(a->info, AST_MODFLAG_LOAD_ORDER)<br>+                ? a->info->load_pri : AST_MODPRI_DEFAULT;<br>+      int b_pri = ast_test_flag(b->info, AST_MODFLAG_LOAD_ORDER)<br>+                ? b->info->load_pri : AST_MODPRI_DEFAULT;<br>+<br>+   /*<br>+    * Returns comparison values for a vector sorted by priority.<br>+         * <0 a_pri < b_pri<br>+     * =0 a_pri == b_pri<br>+  * >0 a_pri > b_pri<br>+     */<br>+  return a_pri - b_pri;<br>+}<br> <br> const char *ast_module_name(const struct ast_module *mod)<br> {<br>@@ -522,8 +541,6 @@<br> #endif<br> }<br> <br>-static enum ast_module_load_result load_resource(const char *resource_name, unsigned int global_symbols_only, unsigned int suppress_logging, struct ast_heap *resource_heap, int required);<br>-<br> #define MODULE_LOCAL_ONLY (void *)-1<br> <br> /*!<br>@@ -572,7 +589,7 @@<br>       return mod;<br> }<br> <br>-static struct ast_module *load_dynamic_module(const char *resource_in, unsigned int global_symbols_only, unsigned int suppress_logging, struct ast_heap *resource_heap)<br>+static struct ast_module *load_dynamic_module(const char *resource_in, unsigned int global_symbols_only, unsigned int suppress_logging)<br> {<br>    char fn[PATH_MAX];<br>    struct ast_module *mod;<br>@@ -1141,13 +1158,13 @@<br> /*! loads a resource based upon resource_name. If global_symbols_only is set<br>  *  only modules with global symbols will be loaded.<br>  *<br>- *  If the ast_heap is provided (not NULL) the module is found and added to the<br>- *  heap without running the module's load() function.  By doing this, modules<br>- *  added to the resource_heap can be initialized later in order by priority.<br>+ *  If the module_vector is provided (not NULL) the module is found and added to the<br>+ *  vector without running the module's load() function.  By doing this, modules<br>+ *  can be initialized later in order by priority and dependencies.<br>  *<br>- *  If the ast_heap is not provided, the module's load function will be executed<br>+ *  If the module_vector is not provided, the module's load function will be executed<br>  *  immediately */<br>-static enum ast_module_load_result load_resource(const char *resource_name, unsigned int global_symbols_only, unsigned int suppress_logging, struct ast_heap *resource_heap, int required)<br>+static enum ast_module_load_result load_resource(const char *resource_name, unsigned int global_symbols_only, unsigned int suppress_logging, struct module_vector *resource_heap, int required)<br> {<br>        struct ast_module *mod;<br>       enum ast_module_load_result res = AST_MODULE_LOAD_SUCCESS;<br>@@ -1160,7 +1177,7 @@<br>             if (global_symbols_only && !ast_test_flag(mod->info, AST_MODFLAG_GLOBAL_SYMBOLS))<br>                  return AST_MODULE_LOAD_SKIP;<br>  } else {<br>-             mod = load_dynamic_module(resource_name, global_symbols_only, suppress_logging, resource_heap);<br>+              mod = load_dynamic_module(resource_name, global_symbols_only, suppress_logging);<br>              if (mod == MODULE_LOCAL_ONLY) {<br>                               return AST_MODULE_LOAD_SKIP;<br>          }<br>@@ -1173,21 +1190,26 @@<br>    }<br> <br>  if (inspect_module(mod)) {<br>-           ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name);<br>-         unload_dynamic_module(mod);<br>-          return required ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_DECLINE;<br>+         goto prestart_error;<br>  }<br> <br>  mod->flags.declined = 0;<br> <br>        if (resource_heap) {<br>-         ast_heap_push(resource_heap, mod);<br>+           if (AST_VECTOR_ADD_SORTED(resource_heap, mod, module_vector_cmp)) {<br>+                  goto prestart_error;<br>+         }<br>             res = AST_MODULE_LOAD_PRIORITY;<br>       } else {<br>              res = start_resource(mod);<br>    }<br> <br>  return res;<br>+<br>+prestart_error:<br>+     ast_log(LOG_WARNING, "Module '%s' could not be loaded.\n", resource_name);<br>+ unload_dynamic_module(mod);<br>+  return required ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_DECLINE;<br> }<br> <br> int ast_load_resource(const char *resource_name)<br>@@ -1235,23 +1257,6 @@<br>        return order;<br> }<br> <br>-static int mod_load_cmp(void *a, void *b)<br>-{<br>- struct ast_module *a_mod = (struct ast_module *) a;<br>-  struct ast_module *b_mod = (struct ast_module *) b;<br>-  /* if load_pri is not set, default is 128.  Lower is better */<br>-       int a_pri = ast_test_flag(a_mod->info, AST_MODFLAG_LOAD_ORDER) ? a_mod->info->load_pri : 128;<br>-       int b_pri = ast_test_flag(b_mod->info, AST_MODFLAG_LOAD_ORDER) ? b_mod->info->load_pri : 128;<br>-<br>-    /*<br>-    * Returns comparison values for a min-heap<br>-   * <0 a_pri > b_pri<br>-     * =0 a_pri == b_pri<br>-  * >0 a_pri < b_pri<br>-     */<br>-  return b_pri - a_pri;<br>-}<br>-<br> AST_LIST_HEAD_NOLOCK(load_retries, load_order_entry);<br> <br> /*! loads modules in order by load_pri, updates mod_count<br>@@ -1259,9 +1264,8 @@<br> */<br> static int load_resource_list(struct load_order *load_order, unsigned int global_symbols, int *mod_count)<br> {<br>-      struct ast_heap *resource_heap;<br>+      struct module_vector resource_heap;<br>   struct load_order_entry *order;<br>-      struct ast_module *mod;<br>       struct load_retries load_retries;<br>     int count = 0;<br>        int res = 0;<br>@@ -1270,7 +1274,9 @@<br> <br>        AST_LIST_HEAD_INIT_NOLOCK(&load_retries);<br> <br>-     if(!(resource_heap = ast_heap_create(8, mod_load_cmp, -1))) {<br>+        if (AST_VECTOR_INIT(&resource_heap, 500)) {<br>+              ast_log(LOG_ERROR, "Failed to initialize module loader.\n");<br>+<br>             return -1;<br>    }<br> <br>@@ -1279,7 +1285,7 @@<br>           enum ast_module_load_result lres;<br> <br>          /* Suppress log messages unless this is the last pass */<br>-             lres = load_resource(order->resource, global_symbols, 1, resource_heap, order->required);<br>+              lres = load_resource(order->resource, global_symbols, 1, &resource_heap, order->required);<br>          ast_debug(3, "PASS 0: %-46s %d %d\n", order->resource, lres, global_symbols);<br>            switch (lres) {<br>               case AST_MODULE_LOAD_SUCCESS:<br>@@ -1303,7 +1309,7 @@<br>                   */<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>@@ -1318,7 +1324,7 @@<br>                       enum ast_module_load_result lres;<br> <br>                  /* Suppress log messages unless this is the last pass */<br>-                     lres = load_resource(order->resource, global_symbols, (i < LOAD_RETRIES - 1), resource_heap, order->required);<br>+                      lres = load_resource(order->resource, global_symbols, (i < LOAD_RETRIES - 1), &resource_heap, order->required);<br>                  ast_debug(3, "PASS %d %-46s %d %d\n", i + 1, order->resource, lres, global_symbols);<br>                     switch (lres) {<br>                       /* These are all retryable. */<br>@@ -1356,7 +1362,8 @@<br>         }<br> <br>  /* second remove modules from heap sorted by priority */<br>-     while ((mod = ast_heap_pop(resource_heap))) {<br>+        for (i = 0; i < AST_VECTOR_SIZE(&resource_heap); i++) {<br>+               struct ast_module *mod = AST_VECTOR_GET(&resource_heap, i);<br>               enum ast_module_load_result lres;<br> <br>          lres = start_resource(mod);<br>@@ -1386,7 +1393,7 @@<br>    if (mod_count) {<br>              *mod_count += count;<br>  }<br>-    ast_heap_destroy(resource_heap);<br>+     AST_VECTOR_FREE(&resource_heap);<br> <br>       return res;<br> }<br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/7605">change 7605</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/7605"/><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: merged </div>
<div style="display:none"> Gerrit-Change-Id: Ia23421197f09789940510b03ebbbf3bf24d51bea </div>
<div style="display:none"> Gerrit-Change-Number: 7605 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Corey Farrell <git@cfware.com> </div>
<div style="display:none"> Gerrit-Reviewer: George Joseph <gjoseph@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins2 </div>
<div style="display:none"> Gerrit-Reviewer: Richard Mudgett <rmudgett@digium.com> </div>