---
 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

Reply via email to