write_prometheus: add support for libmicrohttpd 0.9.45+
[collectd.git] / src / gps.c
index d0cec6c..b529422 100644 (file)
--- a/src/gps.c
+++ b/src/gps.c
 #include "common.h"
 #include "plugin.h"
 #include "utils_time.h"
-#include "configfile.h"
 
 #define CGPS_TRUE                  1
 #define CGPS_FALSE                 0
 #define CGPS_DEFAULT_HOST          "localhost"
-#define CGPS_DEFAULT_PORT          "2947"
-#define CGPS_DEFAULT_TIMEOUT       TIME_T_TO_CDTIME_T (0.015)
-#define CGPS_DEFAULT_PAUSE_READ    TIME_T_TO_CDTIME_T (1)
+#define CGPS_DEFAULT_PORT          "2947" /* DEFAULT_GPSD_PORT */
+#define CGPS_DEFAULT_TIMEOUT       MS_TO_CDTIME_T (15)
 #define CGPS_DEFAULT_PAUSE_CONNECT TIME_T_TO_CDTIME_T (5)
 #define CGPS_MAX_ERROR             100
 #define CGPS_CONFIG                "?WATCH={\"enable\":true,\"json\":true,\"nmea\":false}\r\n"
@@ -49,7 +47,6 @@ typedef struct {
   char *host;
   char *port;
   cdtime_t timeout;
-  cdtime_t pause_read;
   cdtime_t pause_connect;
 } cgps_config_t;
 
@@ -67,6 +64,7 @@ static cgps_data_t cgps_data = {NAN, NAN, NAN, NAN};
 static pthread_t cgps_thread_id;
 static pthread_mutex_t  cgps_data_lock = PTHREAD_MUTEX_INITIALIZER;
 static pthread_mutex_t  cgps_thread_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t   cgps_thread_cond = PTHREAD_COND_INITIALIZER;
 static int cgps_thread_shutdown = CGPS_FALSE;
 static int cgps_thread_running = CGPS_FALSE;
 
@@ -75,27 +73,16 @@ static int cgps_thread_running = CGPS_FALSE;
  */
 static int cgps_thread_pause(cdtime_t pTime)
 {
-  cdtime_t now;
-  now = cdtime ();
-  struct timespec pause_th;
-  CDTIME_T_TO_TIMESPEC (MS_TO_CDTIME_T(10), &pause_th);
-  while (CGPS_TRUE)
-  {
-    if ( (cdtime () - now) > pTime )
-    {
-      break;
-    }
+  cdtime_t until = cdtime() + pTime;
 
-    pthread_mutex_lock (&cgps_thread_lock);
-    if (cgps_thread_shutdown == CGPS_TRUE)
-    {
-      return CGPS_FALSE;
-    }
-    pthread_mutex_unlock (&cgps_thread_lock);
-    nanosleep (&pause_th, NULL);
- }
+  pthread_mutex_lock (&cgps_thread_lock);
+  pthread_cond_timedwait (&cgps_thread_cond, &cgps_thread_lock,
+      &CDTIME_T_TO_TIMESPEC (until));
 
- return CGPS_TRUE;
+  int ret = !cgps_thread_shutdown;
+
+  pthread_mutex_lock (&cgps_thread_lock);
+  return ret;
 }
 
 /**
@@ -157,11 +144,6 @@ static void * cgps_thread (void * pData)
       if (!gps_waiting (&gpsd_conn))
 #endif
       {
-        if (cgps_thread_pause(cgps_config_data.pause_read) == CGPS_FALSE)
-        {
-          goto stop;
-        }
-
         continue;
       }
 
@@ -228,14 +210,10 @@ quit:
  */
 static void cgps_submit (const char *type, gauge_t value, const char *type_instance)
 {
-  value_t values[1];
   value_list_t vl = VALUE_LIST_INIT;
 
-  values[0].gauge = value;
-
-  vl.values = values;
+  vl.values = &(value_t) { .gauge = value };
   vl.values_len = 1;
-  sstrncpy (vl.host, hostname_g, sizeof (vl.host));
   sstrncpy (vl.plugin, "gps", sizeof (vl.plugin));
   sstrncpy (vl.type, type, sizeof (vl.type));
   sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance));
@@ -246,7 +224,7 @@ static void cgps_submit (const char *type, gauge_t value, const char *type_insta
 /**
  * Read the data and submit by piece.
  */
-static int cgps_read ()
+static int cgps_read (void)
 {
   cgps_data_t data_copy;
 
@@ -279,14 +257,28 @@ static int cgps_config (oconfig_item_t *ci)
       cf_util_get_service (child, &cgps_config_data.port);
     else if (strcasecmp ("Timeout", child->key) == 0)
       cf_util_get_cdtime (child, &cgps_config_data.timeout);
-    else if (strcasecmp ("Pauseread", child->key) == 0)
-      cf_util_get_cdtime (child, &cgps_config_data.pause_read);
     else if (strcasecmp ("PauseConnect", child->key) == 0)
       cf_util_get_cdtime (child, &cgps_config_data.pause_connect);
     else
       WARNING ("gps plugin: Ignoring unknown config option \"%s\".", child->key);
   }
 
+  // Controlling the value for timeout:
+  // If set too high it blocks the reading (> 5 s), too low it gets not reading (< 500 us).
+  // To avoid any issues we replace "out of range" value by the default value.
+  if (
+    cgps_config_data.timeout > TIME_T_TO_CDTIME_T(5)
+    ||
+    cgps_config_data.timeout < US_TO_CDTIME_T(500)
+  )
+  {
+    WARNING ("gps plugin: timeout set to %.6f sec. setting to default (%.6f).",
+      CDTIME_T_TO_DOUBLE(cgps_config_data.timeout),
+      CDTIME_T_TO_DOUBLE(CGPS_DEFAULT_TIMEOUT)
+    );
+    cgps_config_data.timeout = CGPS_DEFAULT_TIMEOUT;
+  }
+
   return (0);
 }
 
@@ -303,11 +295,9 @@ static int cgps_init (void)
     return 0;
   }
 
-  DEBUG ("gps plugin: config{host: \"%s\", port: \"%s\", timeout: %.6f sec., \
-pause read: %.3f sec, pause connect: %.3f sec.}",
+  DEBUG ("gps plugin: config{host: \"%s\", port: \"%s\", timeout: %.6f sec., pause connect: %.3f sec.}",
          cgps_config_data.host, cgps_config_data.port,
          CDTIME_T_TO_DOUBLE (cgps_config_data.timeout),
-         CDTIME_T_TO_DOUBLE (cgps_config_data.pause_read),
          CDTIME_T_TO_DOUBLE (cgps_config_data.pause_connect));
 
   status = plugin_thread_create (&cgps_thread_id, NULL, cgps_thread, NULL);
@@ -329,6 +319,7 @@ static int cgps_shutdown (void)
 
   pthread_mutex_lock (&cgps_thread_lock);
   cgps_thread_shutdown = CGPS_TRUE;
+  pthread_cond_broadcast (&cgps_thread_cond);
   pthread_mutex_unlock (&cgps_thread_lock);
 
   pthread_join(cgps_thread_id, &res);
@@ -354,7 +345,6 @@ void module_register (void)
   cgps_config_data.host = sstrdup (CGPS_DEFAULT_HOST);
   cgps_config_data.port = sstrdup (CGPS_DEFAULT_PORT);
   cgps_config_data.timeout = CGPS_DEFAULT_TIMEOUT;
-  cgps_config_data.pause_read = CGPS_DEFAULT_PAUSE_READ;
   cgps_config_data.pause_connect = CGPS_DEFAULT_PAUSE_CONNECT;
 
   plugin_register_complex_config ("gps", cgps_config);