--- src/sigrok.c | 110 +++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 66 insertions(+), 44 deletions(-)
diff --git a/src/sigrok.c b/src/sigrok.c index ea1e95e..89ef61c 100644 --- a/src/sigrok.c +++ b/src/sigrok.c @@ -19,15 +19,22 @@ #include "collectd.h" #include "common.h" #include "plugin.h" + #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> +#include <pthread.h> + #include <glib.h> #include <libsigrok/libsigrok.h> +/* Minimum interval between dispatches coming from this plugin. The RRD + * plugin, at least, complains when written to with sub-second intervals.*/ #define DEFAULT_MIN_WRITE_INTERVAL 1 +static pthread_t sr_thread; +static int sr_thread_running = FALSE; GSList *config_devices; static struct sr_session *session = NULL; static int num_devices; @@ -222,34 +229,27 @@ static void plugin_feed_callback(const struct sr_dev_inst *sdi, } -static int plugin_read(user_data_t *ud) -{ - - sr_session_iteration(FALSE); - - return 0; -} - -static int plugin_init(void) +static void *thread_init(void *arg) { struct sr_dev_driver *drv, **drvlist; struct sr_config *src; GSList *devlist, *drvopts, *l; struct config_device *cfdev; - struct timespec ts; int ret, i; char hwident[512]; + (void)arg; + sr_log_callback_set(cd_logger, NULL); sr_log_loglevel_set(loglevel); if ((ret = sr_init(&sr_ctx)) != SR_OK) { ERROR("Failed to initialize libsigrok: %s.", sr_strerror(ret)); - return 1; + return NULL; } if (!(session = sr_session_new())) - return 1; + return NULL; num_devices = 0; drvlist = sr_driver_list(); @@ -264,37 +264,37 @@ static int plugin_init(void) } if (!drv) { ERROR("sigrok: Unknown driver '%s'.", cfdev->driver); - return 1; + return NULL; } if (sr_driver_init(sr_ctx, drv) != SR_OK) - return 1; + return NULL; drvopts = NULL; if (cfdev->conn) { if (!(src = malloc(sizeof(struct sr_config)))) - return 1; + return NULL; src->key = SR_CONF_CONN; src->data = g_variant_new_string(cfdev->conn); drvopts = g_slist_append(drvopts, src); } if (cfdev->serialcomm) { if (!(src = malloc(sizeof(struct sr_config)))) - return 1; + return NULL; src->key = SR_CONF_SERIALCOMM; src->data = g_variant_new_string(cfdev->serialcomm); drvopts = g_slist_append(drvopts, src); } devlist = sr_driver_scan(drv, drvopts); g_slist_free_full(drvopts, (GDestroyNotify)free_drvopts); - if (!devlist) { - INFO("sigrok: No devices found."); - return 0; - } + if (!devlist) + /* No devices found for this driver. */ + continue; + if (g_slist_length(devlist) > 1) { INFO("sigrok: %d sigrok devices for device entry '%s': must be 1.", g_slist_length(devlist), cfdev->name); - return 1; + return NULL; } cfdev->sdi = devlist->data; g_slist_free(devlist); @@ -305,28 +305,54 @@ static int plugin_init(void) INFO("sigrok: Device '%s' is a %s.", cfdev->name, hwident); if (sr_dev_open(cfdev->sdi) != SR_OK) - return 1; + return NULL; if (sr_session_dev_add(cfdev->sdi) != SR_OK) - return 1; + return NULL; num_devices++; } if (num_devices > 0) { /* Do this only when we're sure there's hardware to talk to. */ - ts.tv_sec = 0; - ts.tv_nsec = 1000000L; - plugin_register_complex_read("sigrok", "sigrok", plugin_read, - &ts, NULL); - if (sr_session_datafeed_callback_add(plugin_feed_callback, NULL) != SR_OK) - return 1; + return NULL; + /* Start acquisition on all devices. */ if (sr_session_start() != SR_OK) - return 1; - } else - sr_session_destroy(); + return NULL; + + /* Main loop, runs forever. */ + sr_session_run(); + + sr_session_stop(); + sr_session_dev_remove_all(); + } + + sr_session_destroy(); + + sr_exit(sr_ctx); + + pthread_exit(NULL); + sr_thread_running = FALSE; + + return NULL; +} + +static int plugin_init(void) +{ + int status; + + if (sr_thread_running) { + ERROR("sigrok: Thread already running."); + return -1; + } + + if ((status = plugin_thread_create(&sr_thread, NULL, thread_init, NULL)) != 0) { + ERROR("sigrok: Failed to create thread: %s.", strerror(status)); + return -1; + } + sr_thread_running = TRUE; return 0; } @@ -336,24 +362,20 @@ static int plugin_shutdown(void) struct config_device *cfdev; GSList *l; - if (num_devices > 0) { - sr_session_stop(); - sr_session_dev_remove_all(); - sr_session_destroy(); + if (sr_thread_running) { + pthread_cancel(sr_thread); + pthread_join(sr_thread, NULL); } for (l = config_devices; l; l = l->next) { cfdev = l->data; free(cfdev->name); - if (cfdev->driver) - free(cfdev->driver); - if (cfdev->conn) - free(cfdev->conn); - if (cfdev->serialcomm) - free(cfdev->serialcomm); + free(cfdev->driver); + free(cfdev->conn); + free(cfdev->serialcomm); + free(cfdev); } - - sr_exit(sr_ctx); + g_slist_free(config_devices); return 0; } -- 1.8.1.2 _______________________________________________ collectd mailing list collectd@verplant.org http://mailman.verplant.org/listinfo/collectd