Implemented support for the module_dependency structure.

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@7317 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2004-04-26 17:13:36 +00:00
parent 29e1a3b55b
commit 04ba0ff394

View File

@ -1,6 +1,9 @@
/* Module manager */ /* Module manager */
/* /*
** Copyright 2002-2004, The OpenBeOS Team. All rights reserved.
** Distributed under the terms of the OpenBeOS License.
**
** Copyright 2001, Thomas Kurschel. All rights reserved. ** Copyright 2001, Thomas Kurschel. All rights reserved.
** Distributed under the terms of the NewOS License. ** Distributed under the terms of the NewOS License.
*/ */
@ -8,20 +11,20 @@
#include <kmodule.h> #include <kmodule.h>
#include <lock.h> #include <lock.h>
#include <Errors.h>
#include <khash.h> #include <khash.h>
#include <malloc.h>
#include <elf.h> #include <elf.h>
#include <string.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h> #include <errno.h>
#define MODULE_HASH_SIZE 16 #define MODULE_HASH_SIZE 16
static bool modules_disable_user_addons = false; static bool modules_disable_user_addons = false;
#define TRACE_MODULE 0 #define TRACE_MODULE
#if TRACE_MODULE #ifdef TRACE_MODULE
# define TRACE(x) dprintf x # define TRACE(x) dprintf x
#else #else
# define TRACE(x) ; # define TRACE(x) ;
@ -50,6 +53,7 @@ typedef enum {
typedef struct module_image { typedef struct module_image {
struct module_image *next; struct module_image *next;
module_info **info; /* the module_info we use */ module_info **info; /* the module_info we use */
module_dependency *dependencies;
char *path; /* the full path for the module */ char *path; /* the full path for the module */
image_id image; image_id image;
int32 ref_count; /* how many ref's to this file */ int32 ref_count; /* how many ref's to this file */
@ -230,6 +234,9 @@ load_module_image(const char *path, module_image **_moduleImage)
goto err1; goto err1;
} }
moduleImage->dependencies = (module_dependency *)elf_lookup_symbol(image, "module_dependencies");
// this is allowed to be NULL
moduleImage->path = strdup(path); moduleImage->path = strdup(path);
if (!moduleImage->path) { if (!moduleImage->path) {
status = B_NO_MEMORY; status = B_NO_MEMORY;
@ -542,6 +549,46 @@ search_module(const char *name)
} }
static status_t
put_dependent_modules(module_dependency *dependencies)
{
int32 i = 0;
if (dependencies == NULL)
return B_OK;
for (; dependencies[i].name != NULL; i++) {
status_t status = put_module(dependencies[i].name);
if (status < B_OK)
return status;
}
return B_OK;
}
static status_t
get_dependent_modules(module_dependency *dependencies)
{
int32 i = 0;
if (dependencies == NULL)
return B_OK;
TRACE(("resolving module dependencies...\n"));
for (; dependencies[i].name != NULL; i++) {
status_t status = get_module(dependencies[i].name, dependencies[i].info);
if (status < B_OK) {
TRACE(("loading dependent module \"%s\" failed!\n", dependencies[i].name));
return status;
}
}
return B_OK;
}
/** Initializes a loaded module depending on its state */ /** Initializes a loaded module depending on its state */
static inline status_t static inline status_t
@ -554,20 +601,32 @@ init_module(module *module)
status_t status; status_t status;
module->state = MODULE_INIT; module->state = MODULE_INIT;
// resolve dependencies
status = get_dependent_modules(module->module_image->dependencies);
if (status < B_OK) {
module->state = MODULE_LOADED;
return status;
}
// init module
TRACE(("initing module %s... \n", module->name)); TRACE(("initing module %s... \n", module->name));
status = module->info->std_ops(B_MODULE_INIT); status = module->info->std_ops(B_MODULE_INIT);
TRACE(("...done (%s)\n", strerror(status))); TRACE(("...done (%s)\n", strerror(status)));
if (!status) if (status >= B_OK)
module->state = MODULE_READY; module->state = MODULE_READY;
else else {
put_dependent_modules(module->module_image->dependencies);
module->state = MODULE_LOADED; module->state = MODULE_LOADED;
}
return status; return status;
} }
case MODULE_READY: case MODULE_READY:
return B_NO_ERROR; return B_OK;
case MODULE_INIT: case MODULE_INIT:
FATAL(("circular reference to %s\n", module->name)); FATAL(("circular reference to %s\n", module->name));
@ -618,6 +677,8 @@ uninit_module(module *module)
if (status == B_NO_ERROR) { if (status == B_NO_ERROR) {
module->state = MODULE_LOADED; module->state = MODULE_LOADED;
put_dependent_modules(module->module_image->dependencies);
return 0; return 0;
} }