// Unload module by name void module_unload(const char* name) { // Get full path to module file, and hash of path char path[60]; unsigned int hash = get_module_path(path, name); // Find loaded module, and unload it module_unload_idx(module_find(hash)); }
//----------------------------------------------- // Called on each tick to safe asynchronous unload module by its requests //----------------------------------------------- void module_tick_unloader() { int idx; for( idx=MAX_NUM_LOADED_MODULES-1; idx>=0; idx--) { if (modules[idx].hdr && modules[idx].hdr->_module_info->lib->can_unload) { // Ask module if it is safe to unload if (modules[idx].hdr->_module_info->lib->can_unload()) module_unload_idx(idx); } } }
void module_unload(const char* name) { module_unload_idx(module_find(name)); }
// Load a module referenced by a 'module_handler_t' structure // Returns index into modules array if successful (or module already loaded) // otherwise returns -1 static int _module_load(module_handler_t* hMod) { int idx; // Get full path to module file, and hash of path char path[60]; unsigned int hash = get_module_path(path, hMod->name); // Check if module already loaded idx = module_find(hash); if (idx >= 0) return idx; // Reset lib (should not be needed, loader should only be called from 'default' lib) *hMod->lib = hMod->default_lib; // Simple lock to prevent multiple attempts to load modules simultaneously (in different tasks) // Not perfect; but should be sufficient static int isLoading = 0; while (isLoading != 0) msleep(10); isLoading = 1; // Find empty slot for (idx=0; idx<MAX_NUM_LOADED_MODULES && modules[idx].hdr; idx++) ; // If no slot found return error if (idx == MAX_NUM_LOADED_MODULES) { moduleload_error(hMod->name, "too many modules loaded"); idx = -1; } else { // Load and relocate module (returns 0 if error) flat_hdr* mod = module_preload(path, hMod->name, hMod->version); if (mod != 0) { // Module is valid. Finalize binding modules[idx].hdr = mod; modules[idx].hName = hash; modules[idx].hMod = hMod; int bind_err = bind_module(hMod, mod->_module_info->lib); // Call module loader if required if (!bind_err && mod->_module_info->lib->loader) { bind_err = mod->_module_info->lib->loader(); } // If any errors, unload module and display error message if (bind_err) { module_unload_idx(idx); moduleload_error(hMod->name, "loader error"); idx = -1; } } else { // module did not load, return invalid index idx = -1; } } // Release lock isLoading = 0; return idx; }