* Fixed missing propagation of the module initialization result; before, you

could get modules whose initialization failed.
* Fixed how built-in modules are initialized.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19231 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2006-11-08 14:47:41 +00:00
parent 4313accfba
commit 669e149b7b
+62 -51
View File
@@ -168,7 +168,7 @@ public:
status_t Init(); status_t Init();
status_t Uninit(); status_t Uninit();
void Get(); status_t Get();
bool Put(); bool Put();
ModuleAddOn *AddOn() const { return fAddOn; } ModuleAddOn *AddOn() const { return fAddOn; }
@@ -188,13 +188,11 @@ Module::Module(ModuleAddOn *addon, module_info *info)
fReferenceCount(0), fReferenceCount(0),
fInitialized(false) fInitialized(false)
{ {
Init();
} }
// destructor // destructor
Module::~Module() Module::~Module()
{ {
Uninit();
} }
// Init // Init
@@ -222,22 +220,29 @@ Module::Uninit()
return error; return error;
} }
// Get
void status_t
Module::Get() Module::Get()
{ {
if (fAddOn != NULL) if (fReferenceCount == 0) {
fReferenceCount++; status_t status = Init();
if (status < B_OK)
return status;
}
fReferenceCount++;
return B_OK;
} }
// Put
bool bool
Module::Put() Module::Put()
{ {
if (fAddOn == NULL) if (--fReferenceCount > 0)
return false; return false;
return (--fReferenceCount == 0 && !(fInfo->flags & B_KEEP_LOADED)); Uninit();
return fAddOn && !(fInfo->flags & B_KEEP_LOADED);
} }
@@ -362,36 +367,40 @@ ModuleManager::~ModuleManager()
delete module; delete module;
} }
// GetModule
status_t status_t
ModuleManager::GetModule(const char *path, module_info **infop) ModuleManager::GetModule(const char *path, module_info **_info)
{ {
status_t error = (path && infop ? B_OK : B_BAD_VALUE); if (path == NULL || _info == NULL)
if (error == B_OK) { return B_BAD_VALUE;
BAutolock _lock(fModules);
Module *module = fModules.FindModule(path); BAutolock _lock(fModules);
if (!module) { status_t error = B_OK;
// module not yet loaded, try to get it
// get the responsible add-on Module *module = fModules.FindModule(path);
ModuleAddOn *addon = NULL; if (module == NULL) {
error = _GetAddOn(path, &addon); // module not yet loaded, try to get it
if (error == B_OK) { // get the responsible add-on
// add-on found, get the module ModuleAddOn *addon = NULL;
if (module_info *info = addon->FindModuleInfo(path)) { error = _GetAddOn(path, &addon);
module = new Module(addon, info); if (error == B_OK) {
fModules.AddModule(module); // add-on found, get the module
} else { if (module_info *info = addon->FindModuleInfo(path)) {
_PutAddOn(addon); module = new Module(addon, info);
error = B_ENTRY_NOT_FOUND; fModules.AddModule(module);
} } else {
_PutAddOn(addon);
error = B_ENTRY_NOT_FOUND;
} }
} }
// "get" the module
if (error == B_OK) {
module->Get();
*infop = module->Info();
}
} }
// "get" the module
if (error == B_OK)
error = module->Get();
if (error == B_OK)
*_info = module->Info();
return error; return error;
} }
@@ -399,20 +408,22 @@ ModuleManager::GetModule(const char *path, module_info **infop)
status_t status_t
ModuleManager::PutModule(const char *path) ModuleManager::PutModule(const char *path)
{ {
status_t error = (path ? B_OK : B_BAD_VALUE); if (path == NULL)
if (error == B_OK) { return B_BAD_VALUE;
BAutolock _lock(fModules);
if (Module *module = fModules.FindModule(path)) { BAutolock _lock(fModules);
if (module->Put()) {
ModuleAddOn *addon = module->AddOn(); if (Module *module = fModules.FindModule(path)) {
fModules.RemoveModule(module); if (module->Put()) {
delete module; ModuleAddOn *addon = module->AddOn();
_PutAddOn(addon); fModules.RemoveModule(module);
} delete module;
} else _PutAddOn(addon);
error = B_BAD_VALUE; }
} } else
return error; return B_BAD_VALUE;
return B_OK;
} }
// GetNextLoadedModuleName // GetNextLoadedModuleName
@@ -607,10 +618,10 @@ _add_builtin_module(module_info *info)
// get_module // get_module
status_t status_t
get_module(const char *path, module_info **vec) get_module(const char *path, module_info **_info)
{ {
TRACE(("get_module(`%s')\n", path)); TRACE(("get_module(`%s')\n", path));
return ModuleManager::Default()->GetModule(path, vec); return ModuleManager::Default()->GetModule(path, _info);
} }
// put_module // put_module