<p>Corey Farrell has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/7605">View Change</a></p><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;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/05/7605/1</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: newchange </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>