Some more work on the Bochs plugins support.

- Added support for loading all plugins of one type using wildcard "*".
- Unloading no longer removes the plugin object. Now the member "loaded" is
  set to 0 and the type of a device plugin is reset.
- Added plugin_cleanup() function to remove plugin objects on Bochs exit.
- Some other related cleanups in the plugins code.
This commit is contained in:
Volker Ruppert 2021-01-08 19:04:41 +00:00
parent 3602ec1cd7
commit 127fd003cc
8 changed files with 76 additions and 53 deletions

View File

@ -175,7 +175,7 @@ device_image_t* bx_hdimage_ctl_c::init_image(const char *image_mode, Bit64u disk
} else {
if (!hdimage_locator_c::module_present(image_mode)) {
#if BX_PLUGINS
PLUG_load_img_plugin(image_mode);
PLUG_load_plugin_var(image_mode, PLUGTYPE_IMG);
#else
BX_PANIC(("Disk image mode '%s' not available", image_mode));
#endif
@ -271,7 +271,7 @@ void hdimage_locator_c::cleanup()
{
#if BX_PLUGINS
while (all != NULL) {
PLUG_unload_img_plugin(all->mode);
PLUG_unload_plugin_type(all->mode, PLUGTYPE_IMG);
}
#endif
}
@ -426,6 +426,9 @@ bool hdimage_detect_image_mode(const char *pathname, const char **image_mode)
bool result = false;
Bit64u image_size = 0;
#if BX_PLUGINS && !defined(BXIMAGE)
PLUG_load_plugin_var("*", PLUGTYPE_IMG);
#endif
int fd = hdimage_open_file(pathname, O_RDONLY, &image_size, NULL);
if (fd < 0) {
return result;

View File

@ -2,7 +2,7 @@
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001-2020 The Bochs Project
// Copyright (C) 2001-2021 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@ -57,7 +57,7 @@ void* bx_netmod_ctl_c::init_module(bx_list_c *base, void *rxh, void *rxstat, bx_
const char *modname = SIM->get_param_enum("ethmod", base)->get_selected();
if (!eth_locator_c::module_present(modname)) {
#if BX_PLUGINS
PLUG_load_net_plugin(modname);
PLUG_load_plugin_var(modname, PLUGTYPE_NET);
#else
BX_PANIC(("could not find networking module '%s'", modname));
#endif
@ -131,7 +131,7 @@ void eth_locator_c::cleanup()
{
#if BX_PLUGINS
while (all != NULL) {
PLUG_unload_net_plugin(all->type);
PLUG_unload_plugin_type(all->type, PLUGTYPE_NET);
}
#endif
}

View File

@ -2,7 +2,7 @@
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2011-2017 The Bochs Project
// Copyright (C) 2011-2021 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@ -668,7 +668,7 @@ void bx_sound_lowlevel_c::cleanup()
{
#if BX_PLUGINS
while (all != NULL) {
PLUG_unload_snd_plugin(all->type);
PLUG_unload_plugin_type(all->type, PLUGTYPE_SND);
}
#endif
}

View File

@ -2,7 +2,7 @@
// $Id$
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2011-2017 The Bochs Project
// Copyright (C) 2011-2021 The Bochs Project
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@ -71,7 +71,7 @@ bx_sound_lowlevel_c* bx_soundmod_ctl_c::get_driver(int driver_id)
const char *modname = sound_driver_names[driver_id];
if (!bx_sound_lowlevel_c::module_present(modname)) {
#if BX_PLUGINS
PLUG_load_snd_plugin(modname);
PLUG_load_plugin_var(modname, PLUGTYPE_SND);
#else
BX_PANIC(("could not find sound driver '%s'", modname));
#endif

View File

@ -6,7 +6,7 @@
//
// Copyright (c) 2005 Fabrice Bellard
// Copyright (C) 2009-2015 Benjamin D Lunt (fys at fysnet net)
// 2009-2020 The Bochs Project
// 2009-2021 The Bochs Project
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
@ -143,7 +143,7 @@ int bx_usbdev_ctl_c::init_device(bx_list_c *portconf, logfunctions *hub, void **
}
if (!usbdev_locator_c::module_present(usbmod_names[modtype])) {
#if BX_PLUGINS
PLUG_load_usb_plugin(usbmod_names[modtype]);
PLUG_load_plugin_var(usbmod_names[modtype], PLUGTYPE_USB);
#else
BX_PANIC(("could not find USB device '%s'", usbmod_names[modtype]));
#endif
@ -246,7 +246,7 @@ void usbdev_locator_c::cleanup()
{
#if BX_PLUGINS
while (all != NULL) {
PLUG_unload_usb_plugin(all->type);
PLUG_unload_plugin_type(all->type, PLUGTYPE_USB);
}
#endif
}

View File

@ -358,6 +358,7 @@ int bxmain(void)
fgets(buf, sizeof(buf), stdin);
}
#endif
plugin_cleanup();
BX_INSTR_EXIT_ENV();
return SIM->get_exit_code();
}

View File

@ -422,28 +422,24 @@ void plugin_init_one(plugin_t *plugin)
}
plugin_t *plugin_unload(plugin_t *plugin)
void plugin_unload(plugin_t *plugin)
{
plugin_t *dead_plug;
if (plugin->initialized)
if (plugin->loaded) {
if (plugin->initialized)
plugin->plugin_fini();
#if defined(WIN32)
FreeLibrary(plugin->handle);
FreeLibrary(plugin->handle);
#else
lt_dlclose(plugin->handle);
lt_dlclose(plugin->handle);
#endif
delete [] plugin->name;
dead_plug = plugin;
plugin = plugin->next;
delete dead_plug;
return plugin;
if (plugin->type < PLUGTYPE_GUI) {
plugin->type = PLUGTYPE_DEV;
}
plugin->loaded = 0;
}
}
void plugin_load(char *name, plugintype_t type)
void plugin_load(const char *name, plugintype_t type)
{
plugin_t *plugin = NULL, *temp;
plugintype_t basetype;
@ -605,8 +601,7 @@ void plugin_abort(void)
/* Plugin system: initialisation of plugins entry points */
/************************************************************************/
void
plugin_startup(void)
void plugin_startup(void)
{
pluginRegisterIRQ = builtinRegisterIRQ;
pluginUnregisterIRQ = builtinUnregisterIRQ;
@ -643,6 +638,24 @@ plugin_startup(void)
#endif
}
void plugin_cleanup(void)
{
#if BX_PLUGINS
plugin_t *dead_plug;
while (plugins != NULL) {
if (plugins->loaded) {
plugin_unload(plugins);
}
delete [] plugins->name;
dead_plug = plugins;
plugins = plugins->next;
delete dead_plug;
}
#endif
}
/************************************************************************/
/* Plugin system: Device registration */
@ -734,30 +747,44 @@ bx_bool pluginDevicePresent(const char *name)
int bx_load_plugin(const char *name, plugintype_t type)
{
char *namecopy = new char[1+strlen(name)];
strcpy(namecopy, name);
plugin_load(namecopy, type);
plugin_t *plugin;
if (!strcmp(name, "*")) {
for (plugin = plugins; plugin; plugin = plugin->next) {
if (!strcmp(plugin->name, name) && (type == plugin->type) &&
!plugin->loaded) {
plugin_load(name, type);
}
}
} else {
plugin_load(name, type);
}
return 1;
}
void bx_unload_plugin(const char *name, bx_bool devflag)
{
plugin_t *plugin, *prev = NULL;
plugin_t *plugin;
for (plugin = plugins; plugin; plugin = plugin->next) {
if (!strcmp(plugin->name, name)) {
if (devflag) {
pluginUnregisterDeviceDevmodel(plugin->name);
}
plugin = plugin_unload(plugin);
if (prev == NULL) {
plugins = plugin;
} else {
prev->next = plugin;
}
plugin_unload(plugin);
break;
}
}
}
void bx_unload_plugin_type(const char *name, plugintype_t type)
{
plugin_t *plugin;
for (plugin = plugins; plugin; plugin = plugin->next) {
if (!strcmp(plugin->name, name) && (plugin->type == type)) {
plugin_unload(plugin);
break;
} else {
prev = plugin;
}
}
}

View File

@ -85,21 +85,15 @@ extern "C" {
#define PLUG_get_plugins_count(a) bx_get_plugins_count(a)
#define PLUG_get_plugin_name(a,b) bx_get_plugin_name(a,b)
#define PLUG_load_plugin(name,type) {bx_load_plugin(#name,type);}
#define PLUG_load_plugin_var(name,type) {bx_load_plugin(name,type);}
#define PLUG_load_gui_plugin(name) bx_load_plugin(name,PLUGTYPE_GUI)
#define PLUG_load_opt_plugin(name) bx_load_plugin(name,PLUGTYPE_OPTIONAL)
#define PLUG_load_snd_plugin(name) bx_load_plugin(name,PLUGTYPE_SND)
#define PLUG_load_net_plugin(name) bx_load_plugin(name,PLUGTYPE_NET)
#define PLUG_load_usb_plugin(name) bx_load_plugin(name,PLUGTYPE_USB)
#define PLUG_load_vga_plugin(name) bx_load_plugin(name,PLUGTYPE_VGA)
#define PLUG_load_img_plugin(name) bx_load_plugin(name,PLUGTYPE_IMG)
#define PLUG_load_user_plugin(name) {bx_load_plugin(name,PLUGTYPE_USER);}
#define PLUG_unload_plugin(name) {bx_unload_plugin(#name,1);}
#define PLUG_unload_opt_plugin(name) bx_unload_plugin(name,1)
#define PLUG_unload_snd_plugin(name) bx_unload_plugin(name,0)
#define PLUG_unload_net_plugin(name) bx_unload_plugin(name,0)
#define PLUG_unload_usb_plugin(name) bx_unload_plugin(name,0)
#define PLUG_unload_img_plugin(name) bx_unload_plugin(name,0)
#define PLUG_unload_user_plugin(name) {bx_unload_plugin(name,1);}
#define PLUG_unload_plugin_type(name,type) {bx_unload_plugin_type(name,type);}
#define DEV_register_ioread_handler(b,c,d,e,f) pluginRegisterIOReadHandler(b,c,d,e,f)
#define DEV_register_iowrite_handler(b,c,d,e,f) pluginRegisterIOWriteHandler(b,c,d,e,f)
@ -122,11 +116,7 @@ extern "C" {
#define PLUG_load_plugin(name,type) {lib##name##_LTX_plugin_init(NULL,type);}
#define PLUG_load_gui_plugin(name) bx_load_plugin2(name,PLUGTYPE_GUI)
#define PLUG_load_opt_plugin(name) bx_load_plugin2(name,PLUGTYPE_OPTIONAL)
#define PLUG_load_snd_plugin(name) bx_load_plugin2(name,PLUGTYPE_SND)
#define PLUG_load_net_plugin(name) bx_load_plugin2(name,PLUGTYPE_NET)
#define PLUG_load_usb_plugin(name) bx_load_plugin2(name,PLUGTYPE_USB)
#define PLUG_load_vga_plugin(name) bx_load_plugin2(name,PLUGTYPE_VGA)
#define PLUG_load_img_plugin(name) bx_load_plugin2(name,PLUGTYPE_IMG)
#define PLUG_unload_plugin(name) {lib##name##_LTX_plugin_fini();}
#define PLUG_unload_opt_plugin(name) bx_unload_opt_plugin(name,1);
@ -301,6 +291,7 @@ typedef struct _device_t
extern device_t *devices;
void plugin_startup(void);
void plugin_cleanup(void);
/* === Device Stuff === */
typedef void (*deviceInitMem_t)(BX_MEM_C *);
@ -349,6 +340,7 @@ const char* bx_get_plugin_name(plugintype_t type, Bit8u index);
#endif
int bx_load_plugin(const char *name, plugintype_t type);
extern void bx_unload_plugin(const char *name, bx_bool devflag);
extern void bx_unload_plugin_type(const char *name, plugintype_t type);
extern void bx_init_plugins(void);
extern void bx_reset_plugins(unsigned);
extern void bx_unload_plugins(void);