unixsock plugin: Fix the initialization of the pthread variable under Mac OS X.
[collectd.git] / src / unixsock.c
index 84d49fd..f6dbf73 100644 (file)
@@ -50,6 +50,7 @@ typedef struct value_cache_s
        int        values_num;
        gauge_t   *gauge;
        counter_t *counter;
+       const data_set_t *ds;
        time_t     time;
        struct value_cache_s *next;
 } value_cache_t;
@@ -73,7 +74,7 @@ static char *sock_file  = NULL;
 static char *sock_group = NULL;
 static int   sock_perms = S_IRWXU | S_IRWXG;
 
-static pthread_t listen_thread = -1;
+static pthread_t listen_thread = NULL;
 
 /* Linked list and auxilliary variables for saving values */
 static value_cache_t   *cache_head = NULL;
@@ -97,6 +98,7 @@ static value_cache_t *cache_search (const char *name)
 } /* value_cache_t *cache_search */
 
 static int cache_alloc_name (char *ret, int ret_len,
+               const char *hostname,
                const char *plugin, const char *plugin_instance,
                const char *type, const char *type_instance)
 {
@@ -108,21 +110,20 @@ static int cache_alloc_name (char *ret, int ret_len,
        if ((plugin_instance == NULL) || (strlen (plugin_instance) == 0))
        {
                if ((type_instance == NULL) || (strlen (type_instance) == 0))
-                       status = snprintf (ret, ret_len, "%s/%s",
-                                       plugin, type);
+                       status = snprintf (ret, ret_len, "%s/%s/%s",
+                                       hostname, plugin, type);
                else
-                       status = snprintf (ret, ret_len, "%s/%s-%s",
-                                       plugin, type, type_instance);
+                       status = snprintf (ret, ret_len, "%s/%s/%s-%s",
+                                       hostname, plugin, type, type_instance);
        }
        else
        {
                if ((type_instance == NULL) || (strlen (type_instance) == 0))
-                       status = snprintf (ret, ret_len, "%s-%s/%s",
-                                       plugin, plugin_instance, type);
+                       status = snprintf (ret, ret_len, "%s/%s-%s/%s",
+                                       hostname, plugin, plugin_instance, type);
                else
-                       status = snprintf (ret, ret_len, "%s-%s/%s-%s",
-                                       plugin, plugin_instance,
-                                       type, type_instance);
+                       status = snprintf (ret, ret_len, "%s/%s-%s/%s-%s",
+                                       hostname, plugin, plugin_instance, type, type_instance);
        }
 
        if ((status < 1) || (status >= ret_len))
@@ -171,7 +172,7 @@ static int cache_insert (const data_set_t *ds, const value_list_t *vl)
        }
 
        if (cache_alloc_name (vc->name, sizeof (vc->name),
-                               vl->plugin, vl->plugin_instance,
+                               vl->host, vl->plugin, vl->plugin_instance,
                                ds->type, vl->type_instance) != 0)
        {
                pthread_mutex_unlock (&cache_lock);
@@ -201,6 +202,7 @@ static int cache_insert (const data_set_t *ds, const value_list_t *vl)
                }
        }
        vc->values_num = ds->ds_num;
+       vc->ds = ds;
 
        vc->next = cache_head;
        cache_head = vc;
@@ -220,6 +222,7 @@ static int cache_update (const data_set_t *ds, const value_list_t *vl)
        int i;
 
        if (cache_alloc_name (name, sizeof (name),
+                               vl->host,
                                vl->plugin, vl->plugin_instance,
                                ds->type, vl->type_instance) != 0)
                return (-1);
@@ -261,20 +264,12 @@ static int cache_update (const data_set_t *ds, const value_list_t *vl)
                                        / (vl->time - vc->time);
                        }
 
-                       DBG ("name = %s; old counter: %llu; new counter: %llu; rate: %lf;",
-                                       name,
-                                       vc->counter[i], vl->values[i].counter,
-                                       vc->gauge[i]);
-
                        vc->counter[i] = vl->values[i].counter;
                }
                else if (ds->ds[i].type == DS_TYPE_GAUGE)
                {
                        vc->gauge[i] = vl->values[i].gauge;
                        vc->counter[i] = 0;
-
-                       DBG ("name, %s; gauge: %lf;",
-                                       name, vc->gauge[i]);
                }
                else
                {
@@ -288,6 +283,7 @@ static int cache_update (const data_set_t *ds, const value_list_t *vl)
                        vc->gauge[i] = NAN;
        } /* for i = 0 .. ds->ds_num */
 
+       vc->ds = ds;
        vc->time = vl->time;
 
        if (vc->time < cache_oldest)
@@ -422,7 +418,8 @@ static int us_open_socket (void)
 
 static int us_handle_getval (FILE *fh, char **fields, int fields_num)
 {
-       char *plugin = fields[1];
+       char *hostname = fields[1];
+       char *plugin;
        char *plugin_instance;
        char *type;
        char *type_instance;
@@ -434,6 +431,11 @@ static int us_handle_getval (FILE *fh, char **fields, int fields_num)
        if (fields_num != 2)
                return (-1);
 
+       plugin = strchr (hostname, '/');
+       if (plugin == NULL)
+               return (-1);
+       *plugin = '\0'; plugin++;
+
        type = strchr (plugin, '/');
        if (type == NULL)
                return (-1);
@@ -454,21 +456,32 @@ static int us_handle_getval (FILE *fh, char **fields, int fields_num)
        }
 
        status = cache_alloc_name (name, sizeof (name),
-                       plugin, plugin_instance, type, type_instance);
+                       hostname, plugin, plugin_instance, type, type_instance);
        if (status != 0)
                return (-1);
 
        pthread_mutex_lock (&cache_lock);
 
+       DBG ("vc = cache_search (%s)", name);
        vc = cache_search (name);
 
-       fprintf (fh, "%i", vc->values_num);
-       for (i = 0; i < vc->values_num; i++)
+       if (vc == NULL)
        {
-               if (vc->gauge[i] == NAN)
-                       fprintf (fh, " NaN");
-               else
-                       fprintf (fh, " %12e", vc->gauge[i]);
+               DBG ("Did not find cache entry.");
+               fprintf (fh, "-1 No such value");
+       }
+       else
+       {
+               DBG ("Found cache entry.");
+               fprintf (fh, "%i", vc->values_num);
+               for (i = 0; i < vc->values_num; i++)
+               {
+                       fprintf (fh, " %s=", vc->ds->ds[i].name);
+                       if (vc->gauge[i] == NAN)
+                               fprintf (fh, "NaN");
+                       else
+                               fprintf (fh, "%12e", vc->gauge[i]);
+               }
        }
 
        /* Free the mutex as soon as possible and definitely before flushing */
@@ -505,7 +518,17 @@ static void *us_handle_client (void *arg)
 
        while (fgets (buffer, sizeof (buffer), fh) != NULL)
        {
-               DBG ("fgets -> buffer = %s", buffer);
+               int len;
+
+               len = strlen (buffer);
+               while ((len > 0)
+                               && ((buffer[len - 1] == '\n') || (buffer[len - 1] == '\r')))
+                       buffer[--len] = '\0';
+
+               if (len == 0)
+                       continue;
+
+               DBG ("fgets -> buffer = %s; len = %i;", buffer, len);
 
                fields_num = strsplit (buffer, fields,
                                sizeof (fields) / sizeof (fields[0]));
@@ -538,6 +561,7 @@ static void *us_server_thread (void *arg)
        int  status;
        int *remote_fd;
        pthread_t th;
+       pthread_attr_t th_attr;
 
        if (us_open_socket () != 0)
                pthread_exit ((void *) 1);
@@ -570,7 +594,10 @@ static void *us_server_thread (void *arg)
 
                DBG ("Spawning child to handle connection on fd #%i", *remote_fd);
 
-               status = pthread_create (&th, NULL, us_handle_client, (void *) remote_fd);
+               pthread_attr_init (&th_attr);
+               pthread_attr_setdetachstate (&th_attr, PTHREAD_CREATE_DETACHED);
+
+               status = pthread_create (&th, &th_attr, us_handle_client, (void *) remote_fd);
                if (status != 0)
                {
                        syslog (LOG_WARNING, "unixsock plugin: pthread_create failed: %s",
@@ -627,12 +654,16 @@ static int us_shutdown (void)
 {
        void *ret;
 
-       if (listen_thread >= 0)
+       if (listen_thread != NULL)
        {
                pthread_kill (listen_thread, SIGTERM);
                pthread_join (listen_thread, &ret);
        }
 
+       plugin_unregister_init ("unixsock");
+       plugin_unregister_write ("unixsock");
+       plugin_unregister_shutdown ("unixsock");
+
        return (0);
 } /* int us_shutdown */