From e8edb8545b49103f6d036c4034e992cf6a66d1b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Tue, 18 Jan 2005 02:37:38 +0000 Subject: [PATCH] A hash_lookup() to the module images was made without having the proper lock held. Added kernel private calls load_module() and unload_module() that can be used to load/unload modules by path. load_module_image() now only mentions when it couldn't load a module when tracing is enabled (because the device manager uses it to determine if an add-on is a module or an old-style driver). git-svn-id: file:///srv/svn/repos/haiku/trunk/current@10821 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/kernel/core/module.c | 70 +++++++++++++++++++++++++++++++++------- 1 file changed, 59 insertions(+), 11 deletions(-) diff --git a/src/kernel/core/module.c b/src/kernel/core/module.c index e0ca9fb788..f116b201e0 100644 --- a/src/kernel/core/module.c +++ b/src/kernel/core/module.c @@ -1,12 +1,14 @@ -/* Module manager */ - /* -** Copyright 2002-2004, Haiku Inc.. All rights reserved. -** Distributed under the terms of the Haiku License. -** -** Copyright 2001, Thomas Kurschel. All rights reserved. -** Distributed under the terms of the NewOS License. -*/ + * Copyright 2002-2005, Haiku Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Copyright 2001, Thomas Kurschel. All rights reserved. + * Distributed under the terms of the NewOS License. + */ + +/* The Module manager + * Manages kernel add-ons and their exported modules. + */ #include @@ -273,7 +275,7 @@ load_module_image(const char *path, module_image **_moduleImage) if (get_image_symbol(image, "modules", B_SYMBOL_TYPE_DATA, (void **)&moduleImage->info) != B_OK) { - FATAL(("load_module_image: Failed to load %s due to lack of 'modules' symbol\n", path)); + TRACE(("load_module_image: Failed to load \"%s\" due to lack of 'modules' symbol\n", path)); status = B_BAD_TYPE; goto err1; } @@ -314,11 +316,15 @@ unload_module_image(module_image *moduleImage, const char *path) { TRACE(("unload_module_image(image = %p, path = %s)\n", moduleImage, path)); + recursive_lock_lock(&sModulesLock); + if (moduleImage == NULL) { // if no image was specified, lookup it up in the hash table moduleImage = (module_image *)hash_lookup(sModuleImagesHash, path); - if (moduleImage == NULL) + if (moduleImage == NULL) { + recursive_lock_unlock(&sModulesLock); return B_ENTRY_NOT_FOUND; + } } if (moduleImage->ref_count != 0) { @@ -326,7 +332,6 @@ unload_module_image(module_image *moduleImage, const char *path) return B_ERROR; } - recursive_lock_lock(&sModulesLock); hash_remove(sModuleImagesHash, moduleImage); recursive_lock_unlock(&sModulesLock); @@ -1055,6 +1060,49 @@ dump_modules(int argc, char **argv) // Exported Kernel API (private part) +/** Unloads a module in case it's not in use. This is the counterpart + * to load_module(). + */ + +status_t +unload_module(const char *path) +{ + struct module_image *moduleImage; + + recursive_lock_lock(&sModulesLock); + moduleImage = (module_image *)hash_lookup(sModuleImagesHash, path); + recursive_lock_unlock(&sModulesLock); + + if (moduleImage == NULL) + return B_ENTRY_NOT_FOUND; + + put_module_image(moduleImage); + return B_OK; +} + + +/** Unlike get_module(), this function lets you specify the add-on to + * be loaded by path. + * However, you must not use the exported modules without having called + * get_module() on them. When you're done with the NULL terminated + * \a modules array, you have to call unload_module(), no matter if + * you're actually using any of the modules or not - of course, the + * add-on won't be unloaded until the last put_module(). + */ + +status_t +load_module(const char *path, module_info ***_modules) +{ + module_image *moduleImage; + status_t status = get_module_image(path, &moduleImage); + if (status != B_OK) + return status; + + *_modules = moduleImage->info; + return B_OK; +} + + /** Setup the module structures and data for use - must be called * before any other module call. */