#include <glib.h>
-static GSList *modules_list;
+#define module_iterate_all_priorities(priority) \
+ for (priority = (MODULE_PRIORITY_MAX - 1); \
+ priority > MODULE_PRIORITY_MIN; --priority) \
+
+#define module_iterate_all_modules(priority, iter) \
+ module_iterate_all_priorities(priority) \
+ gslist_for_each_item(iter, modules_list[priority])
+
+#define module_iterate_all_modules_safe(priority, iter, next, module) \
+ module_iterate_all_priorities(priority) \
+ gslist_for_each_safe(modules_list[priority], iter, next, module)
+
+
+static GSList *modules_list[MODULE_PRIORITY_MAX];
+
+static void assert_priority(enum module_priority priority)
+{
+ switch(priority) {
+ case MODULE_PRIORITY_LATE:
+ case MODULE_PRIORITY_NORMAL:
+ case MODULE_PRIORITY_HIGH:
+ case MODULE_PRIORITY_EARLY:
+ return;
+ default:
+ _E("Invalid module priority: %d", priority);
+ assert(0);
+ }
+}
void add_module(const struct module_ops *module)
{
ret_msg_if(!module, "Invalid module handler\n");
- if (module->priority == MODULE_PRIORITY_EARLY)
- modules_list = g_slist_prepend(modules_list, (gpointer)module);
- else
- modules_list = g_slist_append(modules_list, (gpointer)module);
+ enum module_priority p = module->priority;
+ assert_priority(p);
+
+ modules_list[p] = g_slist_prepend(modules_list[p], (gpointer)module);
}
void remove_module(const struct module_ops *module)
{
- modules_list = g_slist_remove(modules_list, (gpointer)module);
+ ret_msg_if(!module, "Invalid module handler\n");
+
+ enum module_priority p = module->priority;
+ assert_priority(p);
+
+ modules_list[p] = g_slist_remove(modules_list[p], (gpointer)module);
}
const struct module_ops *find_module(const char *name)
{
GSList *iter;
const struct module_ops *module;
+ int priority;
- gslist_for_each_item(iter, modules_list) {
+ module_iterate_all_modules(priority, iter) {
module = (struct module_ops *)iter->data;
- if (!strncmp(module->name, name, strlen(module->name) + 1) &&
- (module->initalized == MODULE_INITIALIZED))
- return module;
+ if (module->initalized != MODULE_INITIALIZED)
+ continue;
+ if (strncmp(module->name, name, strlen(module->name) + 1) != 0)
+ continue;
+ return module;
}
+
return NULL;
}
{
GSList *iter, *next;
const struct module_ops *module;
- int ret;
+ int priority, ret;
- gslist_for_each_safe(modules_list, iter, next, module) {
- module = (const struct module_ops *)iter->data;
+ module_iterate_all_modules_safe(priority, iter, next, module) {
_D("check runtime support [%s] module\n", module->name);
if (!module->check_runtime_support)
}
}
-static void module_initcall_level(void *data, int priority)
+static void module_init_per_priority(void *data, enum module_priority priority)
{
GSList *iter;
struct module_ops *module;
int ret;
- gslist_for_each_item(iter, modules_list) {
- module = (struct module_ops *)iter->data;
+ assert_priority(priority);
+ gslist_for_each_item(iter, modules_list[priority]) {
+ module = (struct module_ops *)iter->data;
assert(module);
- if (module->priority < priority)
- continue;
-
if (module->initalized != MODULE_NONINITIALIZED)
continue;
void modules_init(void *data)
{
- module_initcall_level(data, MODULE_PRIORITY_HIGH);
+ module_init_per_priority(data, MODULE_PRIORITY_EARLY);
+ module_init_per_priority(data, MODULE_PRIORITY_HIGH);
}
void modules_init_late(void *data)
{
- module_initcall_level(data, MODULE_PRIORITY_NORMAL);
- module_initcall_level(data, MODULE_PRIORITY_LATE);
+ module_init_per_priority(data, MODULE_PRIORITY_EARLY);
+ module_init_per_priority(data, MODULE_PRIORITY_HIGH);
+ module_init_per_priority(data, MODULE_PRIORITY_NORMAL);
+ module_init_per_priority(data, MODULE_PRIORITY_LATE);
}
void modules_exit(void *data)
GSList *iter;
struct module_ops *module;
int ret;
+ int priority;
- gslist_for_each_item(iter, modules_list) {
+ module_iterate_all_modules(priority, iter) {
module = (struct module_ops *)iter->data;
if (module->exit && (module->initalized == MODULE_INITIALIZED)) {
module->initalized = MODULE_NONINITIALIZED;
ret = module->exit(data);
- if (ret < 0)
+ if (ret < 0) {
_E("Fail to deinitialize [%s] module\n", module->name);
- else
- _D("Deinitialize [%s] module\n", module->name);
+ continue;
+ }
+ _D("Deinitialize [%s] module\n", module->name);
}
}
- g_slist_free(modules_list);
- modules_list = NULL;
+
+ module_iterate_all_priorities(priority) {
+ g_slist_free(modules_list[priority]);
+ modules_list[priority] = NULL;
+ }
}
void modules_restore(void *data)
{
- struct module_ops *module;
GSList *iter;
+ struct module_ops *module;
int ret;
+ int priority;
- gslist_for_each_item(iter, modules_list) {
+ module_iterate_all_modules(priority, iter) {
module = (struct module_ops *)iter->data;
assert(module);
{
GSList *iter;
const struct module_ops *module;
+ int priority;
- gslist_for_each_item(iter, modules_list) {
+ module_iterate_all_modules(priority, iter) {
module = (struct module_ops *)iter->data;
if (module->initalized != MODULE_INITIALIZED)
continue;
+ if (!module->dump)
+ continue;
+
_D("dump [%s] module\n", module->name);
- if (module->dump)
- module->dump(fp, mode, module->dump_data);
+ module->dump(fp, mode, module->dump_data);
}
}
struct module_ops *module;
GSList *list_iter;
GVariantBuilder builder, *sub_builder;
+ int priority;
g_variant_builder_init(&builder, G_VARIANT_TYPE_TUPLE);
sub_builder = g_variant_builder_new(G_VARIANT_TYPE("as"));
- gslist_for_each_item(list_iter, modules_list) {
+ module_iterate_all_modules(priority, list_iter) {
module = (struct module_ops *)list_iter->data;
if (module->initalized != MODULE_INITIALIZED)
continue;