There is no need to keep a separate list of the modules. It requires additional memory allocation and additional error handling. Now grub_dl_add() can only fail if the module is already loaded.
ChangeLog: * include/grub/dl.h (struct grub_dl): Add next field. * kern/dl.c: Remove struct grub_dl_list. Use mod->next to iterate over modules. --- include/grub/dl.h | 1 + kern/dl.c | 55 +++++++++++++++++++---------------------------------- 2 files changed, 21 insertions(+), 35 deletions(-) diff --git a/include/grub/dl.h b/include/grub/dl.h index 3f8b328..55cc6cc 100644 --- a/include/grub/dl.h +++ b/include/grub/dl.h @@ -82,6 +82,7 @@ struct grub_dl Elf_Sym *symtab; void (*init) (struct grub_dl *mod); void (*fini) (void); + struct grub_dl *next; }; typedef struct grub_dl *grub_dl_t; diff --git a/kern/dl.c b/kern/dl.c index e2382d6..81c211e 100644 --- a/kern/dl.c +++ b/kern/dl.c @@ -40,31 +40,17 @@ -struct grub_dl_list -{ - struct grub_dl_list *next; - grub_dl_t mod; -}; -typedef struct grub_dl_list *grub_dl_list_t; - -static grub_dl_list_t grub_dl_head; +static grub_dl_t grub_dl_head; static grub_err_t grub_dl_add (grub_dl_t mod) { - grub_dl_list_t l; - if (grub_dl_get (mod->name)) return grub_error (GRUB_ERR_BAD_MODULE, "`%s' is already loaded", mod->name); - l = (grub_dl_list_t) grub_malloc (sizeof (*l)); - if (! l) - return grub_errno; - - l->mod = mod; - l->next = grub_dl_head; - grub_dl_head = l; + mod->next = grub_dl_head; + grub_dl_head = mod; return GRUB_ERR_NONE; } @@ -72,13 +58,12 @@ grub_dl_add (grub_dl_t mod) static void grub_dl_remove (grub_dl_t mod) { - grub_dl_list_t *p, q; + grub_dl_t *p, q; for (p = &grub_dl_head, q = *p; q; p = &q->next, q = *p) - if (q->mod == mod) + if (q == mod) { *p = q->next; - grub_free (q); return; } } @@ -86,11 +71,11 @@ grub_dl_remove (grub_dl_t mod) grub_dl_t grub_dl_get (const char *name) { - grub_dl_list_t l; + grub_dl_t mod; - for (l = grub_dl_head; l; l = l->next) - if (grub_strcmp (name, l->mod->name) == 0) - return l->mod; + for (mod = grub_dl_head; mod; mod = mod->next) + if (grub_strcmp (name, mod->name) == 0) + return mod; return 0; } @@ -98,10 +83,10 @@ grub_dl_get (const char *name) void grub_dl_iterate (int (*hook) (grub_dl_t mod)) { - grub_dl_list_t l; + grub_dl_t mod; - for (l = grub_dl_head; l; l = l->next) - if (hook (l->mod)) + for (mod = grub_dl_head; mod; mod = mod->next) + if (hook (mod)) break; } @@ -684,17 +669,17 @@ grub_dl_unload_unneeded (void) { /* Because grub_dl_remove modifies the list of modules, this implementation is tricky. */ - grub_dl_list_t p = grub_dl_head; + grub_dl_t mod = grub_dl_head; - while (p) + while (mod) { - if (grub_dl_unload (p->mod)) + if (grub_dl_unload (mod)) { - p = grub_dl_head; + mod = grub_dl_head; continue; } - p = p->next; + mod = mod->next; } } @@ -704,13 +689,13 @@ grub_dl_unload_all (void) { while (grub_dl_head) { - grub_dl_list_t p; + grub_dl_t mod; grub_dl_unload_unneeded (); /* Force to decrement the ref count. This will purge pre-loaded modules and manually inserted modules. */ - for (p = grub_dl_head; p; p = p->next) - p->mod->ref_count--; + for (mod = grub_dl_head; mod; mod = mod->next) + mod->ref_count--; } } _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org http://lists.gnu.org/mailman/listinfo/grub-devel