better cleanup of device/plugin resources

This commit is contained in:
Bert Vermeulen 2011-04-04 05:13:29 +02:00
parent 896a19fd65
commit 8722c31e26
6 changed files with 47 additions and 65 deletions

View File

@ -38,7 +38,8 @@ int sr_init(void)
*/ */
int sr_exit(void) int sr_exit(void)
{ {
sr_device_close_all();
sr_cleanup_hwplugins();
return SR_OK; return SR_OK;
} }

View File

@ -26,6 +26,7 @@ extern struct sr_global *global;
GSList *devices = NULL; GSList *devices = NULL;
void sr_device_scan(void) void sr_device_scan(void)
{ {
GSList *plugins, *l; GSList *plugins, *l;
@ -40,43 +41,11 @@ void sr_device_scan(void)
*/ */
for (l = plugins; l; l = l->next) { for (l = plugins; l; l = l->next) {
plugin = l->data; plugin = l->data;
sr_device_plugin_init(plugin); sr_init_hwplugins(plugin);
} }
} }
int sr_device_plugin_init(struct sr_device_plugin *plugin)
{
int num_devices, num_probes, i;
sr_info("initializing %s plugin", plugin->name);
num_devices = plugin->init(NULL);
for (i = 0; i < num_devices; i++) {
num_probes = (int)plugin->get_device_info(i, SR_DI_NUM_PROBES);
sr_device_new(plugin, i, num_probes);
}
return num_devices;
}
void sr_device_close_all(void)
{
int ret;
struct sr_device *device;
while (devices) {
device = devices->data;
if (device->plugin && device->plugin->closedev) {
ret = device->plugin->closedev(device->plugin_index);
if (ret != SR_OK) {
sr_err("dev: %s: could not close device %d",
__func__, device->plugin_index);
}
}
sr_device_destroy(device);
}
}
GSList *sr_device_list(void) GSList *sr_device_list(void)
{ {
@ -111,8 +80,6 @@ void sr_device_clear(struct sr_device *device)
{ {
unsigned int pnum; unsigned int pnum;
/* TODO: Plugin-specific clear call? */
if (!device->probes) if (!device->probes)
return; return;
@ -120,24 +87,6 @@ void sr_device_clear(struct sr_device *device)
sr_device_probe_clear(device, pnum); sr_device_probe_clear(device, pnum);
} }
void sr_device_destroy(struct sr_device *device)
{
unsigned int pnum;
/*
* TODO: Plugin-specific destroy call, need to decrease refcount
* in plugin.
*/
devices = g_slist_remove(devices, device);
if (device->probes) {
for (pnum = 1; pnum <= g_slist_length(device->probes); pnum++)
sr_device_probe_clear(device, pnum);
g_slist_free(device->probes);
}
g_free(device);
}
void sr_device_probe_clear(struct sr_device *device, int probenum) void sr_device_probe_clear(struct sr_device *device, int probenum)
{ {
struct sr_probe *p; struct sr_probe *p;

View File

@ -482,7 +482,7 @@ static void hw_cleanup(void)
GSList *l; GSList *l;
struct sr_device_instance *sdi; struct sr_device_instance *sdi;
/* Properly close all devices. */ /* Properly close and free all devices. */
for (l = device_instances; l; l = l->next) { for (l = device_instances; l; l = l->next) {
sdi = l->data; sdi = l->data;
if (sdi->serial->fd != -1) if (sdi->serial->fd != -1)

View File

@ -107,20 +107,47 @@ GSList *sr_list_hwplugins(void)
return plugins; return plugins;
} }
int sr_init_hwplugins(struct sr_device_plugin *plugin)
{
int num_devices, num_probes, i;
g_message("initializing %s plugin", plugin->name);
num_devices = plugin->init(NULL);
for (i = 0; i < num_devices; i++) {
num_probes = (int)plugin->get_device_info(i, SR_DI_NUM_PROBES);
sr_device_new(plugin, i, num_probes);
}
return num_devices;
}
void sr_cleanup_hwplugins(void)
{
struct sr_device_plugin *plugin;
GSList *l;
for (l = plugins; l; l = l->next) {
plugin = l->data;
if (plugin->cleanup)
plugin->cleanup();
}
}
struct sr_device_instance *sr_device_instance_new(int index, int status, struct sr_device_instance *sr_device_instance_new(int index, int status,
const char *vendor, const char *model, const char *version) const char *vendor, const char *model, const char *version)
{ {
struct sr_device_instance *sdi; struct sr_device_instance *sdi;
if (!(sdi = malloc(sizeof(struct sr_device_instance)))) if (!(sdi = g_malloc(sizeof(struct sr_device_instance))))
return NULL; return NULL;
sdi->index = index; sdi->index = index;
sdi->status = status; sdi->status = status;
sdi->instance_type = -1; sdi->instance_type = -1;
sdi->vendor = vendor ? strdup(vendor) : NULL; sdi->vendor = vendor ? g_strdup(vendor) : NULL;
sdi->model = model ? strdup(model) : strdup("(unknown)"); sdi->model = model ? g_strdup(model) : NULL;
sdi->version = version ? strdup(version) : NULL; sdi->version = version ? g_strdup(version) : NULL;
sdi->priv = NULL; sdi->priv = NULL;
sdi->usb = NULL; sdi->usb = NULL;
@ -159,10 +186,14 @@ void sr_device_instance_free(struct sr_device_instance *sdi)
break; break;
} }
free(sdi->vendor); if (sdi->priv)
free(sdi->model); g_free(sdi->priv);
free(sdi->version);
free(sdi); g_free(sdi->vendor);
g_free(sdi->model);
g_free(sdi->version);
g_free(sdi);
} }
#ifdef HAVE_LIBUSB_1_0 #ifdef HAVE_LIBUSB_1_0

View File

@ -54,6 +54,7 @@ struct sr_session *sr_session_new(void)
void sr_session_destroy(void) void sr_session_destroy(void)
{ {
g_slist_free(session->devices); g_slist_free(session->devices);
/* TODO: Loop over protocol decoders and free them. */ /* TODO: Loop over protocol decoders and free them. */

View File

@ -40,8 +40,7 @@ void sr_datastore_put(struct sr_datastore *ds, void *data, unsigned int length,
/*--- device.c --------------------------------------------------------------*/ /*--- device.c --------------------------------------------------------------*/
void sr_device_scan(void); void sr_device_scan(void);
int sr_device_plugin_init(struct sr_device_plugin *plugin); int sr_init_hwplugins(struct sr_device_plugin *plugin);
void sr_device_close_all(void);
GSList *sr_device_list(void); GSList *sr_device_list(void);
struct sr_device *sr_device_new(struct sr_device_plugin *plugin, struct sr_device *sr_device_new(struct sr_device_plugin *plugin,
int plugin_index, int num_probes); int plugin_index, int num_probes);
@ -68,6 +67,7 @@ int sr_filter_probes(int in_unitsize, int out_unitsize, int *probelist,
/*--- hwplugin.c ------------------------------------------------------------*/ /*--- hwplugin.c ------------------------------------------------------------*/
GSList *sr_list_hwplugins(void); GSList *sr_list_hwplugins(void);
void sr_cleanup_hwplugins(void);
/* Generic device instances */ /* Generic device instances */
struct sr_device_instance *sr_device_instance_new(int index, struct sr_device_instance *sr_device_instance_new(int index,