From a5def94f4348a000144d47ee3525986174c53e67 Mon Sep 17 00:00:00 2001 From: Anders Blomdell <anders.blomdell@control.lth.se> Date: Wed, 27 Feb 2019 12:50:23 +0100 Subject: [PATCH] Clean up unused devices after channel install --- moberg.c | 32 +++++++++++++---------- moberg_channel.h | 67 ++++++++++++++++++++++++++++++++++++++++++++++++ moberg_config.c | 15 +++++++++++ moberg_device.c | 8 ++++++ moberg_device.h | 2 ++ 5 files changed, 111 insertions(+), 13 deletions(-) create mode 100644 moberg_channel.h diff --git a/moberg.c b/moberg.c index f66eac7..bc9e529 100644 --- a/moberg.c +++ b/moberg.c @@ -14,12 +14,6 @@ #include <moberg_config.h> #include <moberg_parser.h> -static struct deferred_action { - struct deferred_action *next; - int (*action)(void *param); - void *param; -} *deferred_action = NULL; - struct moberg { struct moberg_config *config; struct channel_list { @@ -28,6 +22,23 @@ struct moberg { } analog_in, analog_out, digital_in, digital_out, encoder_in; }; +static struct deferred_action { + struct deferred_action *next; + int (*action)(void *param); + void *param; +} *deferred_action = NULL; + +static void run_deferred_actions() +{ + while (deferred_action) { + fprintf(stderr, "RUNNING deferred\n"); + struct deferred_action *deferred = deferred_action; + deferred_action = deferred_action->next; + deferred->action(deferred->param); + free(deferred); + } +} + static int channel_list_set(struct channel_list *list, int index, struct moberg_channel *value) @@ -253,6 +264,7 @@ struct moberg *moberg_new( /* Parse environment overrides */ } install_config(result); + run_deferred_actions(); err: return result; @@ -269,13 +281,7 @@ void moberg_free(struct moberg *moberg) channel_list_free(&moberg->encoder_in); free(moberg); } - while (deferred_action) { - fprintf(stderr, "RUNNING deferred\n"); - struct deferred_action *deferred = deferred_action; - deferred_action = deferred_action->next; - deferred->action(deferred->param); - free(deferred); - } + run_deferred_actions(); } enum moberg_status moberg_start( diff --git a/moberg_channel.h b/moberg_channel.h new file mode 100644 index 0000000..2045b21 --- /dev/null +++ b/moberg_channel.h @@ -0,0 +1,67 @@ +#ifndef __MOBERG_CHANNEL_H__ +#define __MOBERG_CHANNEL_H__ + +#include <moberg.h> + +enum moberg_channel_kind { + chan_ANALOGIN, + chan_ANALOGOUT, + chan_DIGITALIN, + chan_DIGITALOUT, + chan_ENCODERIN +}; + +struct moberg_channel { + struct moberg_channel_context *context; + + /* Use-count of channel, when it reaches zero, channel will be free'd */ + int (*up)(struct moberg_channel *channel); + int (*down)(struct moberg_channel *channel); + + /* Channel open and close */ + int (*open)(struct moberg_channel *channel); + int (*close)(struct moberg_channel *channel); + + /* I/O operations */ + enum moberg_channel_kind kind; + union moberg_channel_action { + struct { + struct moberg_channel_analog_in *context; + int (*read)(struct moberg_channel_analog_in *, double *value); + } analog_in; + struct { + struct moberg_channel_analog_out *context; + int (*write)(struct moberg_channel_context *, double value); + } analog_out; + struct { + struct moberg_channel_digital_in *context; + int (*read)(struct moberg_channel_context *, int *value); + } digital_in; + struct { + struct moberg_channel_digital_out *context; + int (*write)(struct moberg_channel_context *, int value); + } digital_out; + struct { + struct moberg_channel_encoder_in *context; + int (*read)(struct moberg_channel_context *, long *value); + } encoder_in; + } action; +}; + +struct moberg_channel_map { + struct moberg_device *device; + int (*map)(struct moberg_device* device, + struct moberg_channel *channel); +}; + +struct moberg_channel_install { + struct moberg *context; + int (*channel)(struct moberg *context, + int index, + struct moberg_device* device, + struct moberg_channel *channel); +}; + + + +#endif diff --git a/moberg_config.c b/moberg_config.c index aac3855..6f7e6e4 100644 --- a/moberg_config.c +++ b/moberg_config.c @@ -76,6 +76,21 @@ int moberg_config_install_channels(struct moberg_config *config, for (struct device_entry *d = config->device_head ; d ; d = d->next) { result &= moberg_device_install_channels(d->device, install); } + struct device_entry *device = config->device_head; + struct device_entry **previous = &config->device_head; + while (device) { + struct device_entry *next = device->next; + if (moberg_device_in_use(device->device)) { + previous = &device->next; + } else { + fprintf(stderr, "FREE\n"); + moberg_device_free(device->device); + free(device); + *previous = next; + } + device = next; + } + return result; } diff --git a/moberg_device.c b/moberg_device.c index a6e6d86..b2daf2f 100644 --- a/moberg_device.c +++ b/moberg_device.c @@ -90,6 +90,14 @@ void moberg_device_free(struct moberg_device *device) free(device); } +int moberg_device_in_use(struct moberg_device *device) +{ + device->driver.up(device->device_context); + int use = device->driver.down(device->device_context); + fprintf(stderr, "IN_USE: %d\n", use); + return use > 1; +} + int moberg_device_parse_config(struct moberg_device *device, struct moberg_parser_context *parser) { diff --git a/moberg_device.h b/moberg_device.h index 6a5085e..de4a90d 100644 --- a/moberg_device.h +++ b/moberg_device.h @@ -35,6 +35,8 @@ struct moberg_device *moberg_device_new(const char *driver); void moberg_device_free(struct moberg_device *device); +int moberg_device_in_use(struct moberg_device *device); + int moberg_device_parse_config(struct moberg_device* device, struct moberg_parser_context *context); -- GitLab