rrdtool plugin: Fix a possible race condition at startup.
[collectd.git] / src / rrdtool.c
index 2e1727a..27e64c1 100644 (file)
@@ -621,6 +621,7 @@ static void *rrd_queue_thread (void *data)
                rrd_cache_t *cache_entry;
                char **values;
                int    values_num;
+               int    status;
                int    i;
 
                 pthread_mutex_lock (&queue_lock);
@@ -628,7 +629,6 @@ static void *rrd_queue_thread (void *data)
                 while (true)
                 {
                   struct timespec ts_wait;
-                  int status;
 
                   while ((flushq_head == NULL) && (queue_head == NULL)
                       && (do_shutdown == 0))
@@ -704,17 +704,28 @@ static void *rrd_queue_thread (void *data)
                 * we make a copy of it's values */
                pthread_mutex_lock (&cache_lock);
 
-               c_avl_get (cache, queue_entry->filename, (void *) &cache_entry);
+               status = c_avl_get (cache, queue_entry->filename,
+                               (void *) &cache_entry);
 
-               values = cache_entry->values;
-               values_num = cache_entry->values_num;
+               if (status == 0)
+               {
+                       values = cache_entry->values;
+                       values_num = cache_entry->values_num;
 
-               cache_entry->values = NULL;
-               cache_entry->values_num = 0;
-               cache_entry->flags = FLAG_NONE;
+                       cache_entry->values = NULL;
+                       cache_entry->values_num = 0;
+                       cache_entry->flags = FLAG_NONE;
+               }
 
                pthread_mutex_unlock (&cache_lock);
 
+               if (status != 0)
+               {
+                       sfree (queue_entry->filename);
+                       sfree (queue_entry);
+                       continue;
+               }
+
                /* Update `tv_next_update' */
                if (write_rate > 0.0) 
                 {
@@ -968,6 +979,15 @@ static int rrd_cache_insert (const char *filename,
 
        pthread_mutex_lock (&cache_lock);
 
+       /* This shouldn't happen, but it did happen at least once, so we'll be
+        * careful. */
+       if (cache == NULL)
+       {
+               pthread_mutex_unlock (&cache_lock);
+               WARNING ("rrdtool plugin: cache == NULL.");
+               return (-1);
+       }
+
        c_avl_get (cache, filename, (void *) &rc);
 
        if (rc == NULL)
@@ -1159,6 +1179,8 @@ static int rrd_config (const char *key, const char *value)
                {
                        fprintf (stderr, "rrdtool: `CacheTimeout' must "
                                        "be greater than 0.\n");
+                       ERROR ("rrdtool: `CacheTimeout' must "
+                                       "be greater than 0.\n");
                        return (1);
                }
                cache_timeout = tmp;
@@ -1170,6 +1192,8 @@ static int rrd_config (const char *key, const char *value)
                {
                        fprintf (stderr, "rrdtool: `CacheFlush' must "
                                        "be greater than 0.\n");
+                       ERROR ("rrdtool: `CacheFlush' must "
+                                       "be greater than 0.\n");
                        return (1);
                }
                cache_flush_timeout = tmp;
@@ -1213,6 +1237,8 @@ static int rrd_config (const char *key, const char *value)
                {
                        fprintf (stderr, "rrdtool: `RRARows' must "
                                        "be greater than 0.\n");
+                       ERROR ("rrdtool: `RRARows' must "
+                                       "be greater than 0.\n");
                        return (1);
                }
                rrarows = tmp;
@@ -1239,6 +1265,7 @@ static int rrd_config (const char *key, const char *value)
                        if (tmp_alloc == NULL)
                        {
                                fprintf (stderr, "rrdtool: realloc failed.\n");
+                               ERROR ("rrdtool: realloc failed.\n");
                                free (value_copy);
                                return (1);
                        }
@@ -1262,6 +1289,8 @@ static int rrd_config (const char *key, const char *value)
                {
                        fprintf (stderr, "rrdtool: `XFF' must "
                                        "be in the range 0 to 1 (exclusive).");
+                       ERROR ("rrdtool: `XFF' must "
+                                       "be in the range 0 to 1 (exclusive).");
                        return (1);
                }
                xff = tmp;