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