Bumped version to 4.3.1; Updated ChangeLog.
[collectd.git] / src / utils_cache.c
index 5795e7d..9a9e9be 100644 (file)
@@ -56,6 +56,43 @@ static int cache_compare (const cache_entry_t *a, const cache_entry_t *b)
   return (strcmp (a->name, b->name));
 } /* int cache_compare */
 
+static cache_entry_t *cache_alloc (int values_num)
+{
+  cache_entry_t *ce;
+
+  ce = (cache_entry_t *) malloc (sizeof (cache_entry_t));
+  if (ce == NULL)
+  {
+    ERROR ("utils_cache: cache_alloc: malloc failed.");
+    return (NULL);
+  }
+  memset (ce, '\0', sizeof (cache_entry_t));
+  ce->values_num = values_num;
+
+  ce->values_gauge = (gauge_t *) calloc (values_num, sizeof (gauge_t));
+  ce->values_counter = (counter_t *) calloc (values_num, sizeof (counter_t));
+  if ((ce->values_gauge == NULL) || (ce->values_counter == NULL))
+  {
+    sfree (ce->values_gauge);
+    sfree (ce->values_counter);
+    sfree (ce);
+    ERROR ("utils_cache: cache_alloc: calloc failed.");
+    return (NULL);
+  }
+
+  return (ce);
+} /* cache_entry_t *cache_alloc */
+
+static void cache_free (cache_entry_t *ce)
+{
+  if (ce == NULL)
+    return;
+
+  sfree (ce->values_gauge);
+  sfree (ce->values_counter);
+  sfree (ce);
+} /* void cache_free */
+
 static int uc_send_notification (const char *name)
 {
   cache_entry_t *ce = NULL;
@@ -70,8 +107,6 @@ static int uc_send_notification (const char *name)
 
   notification_t n;
 
-  memset (&n, '\0', sizeof (n));
-
   name_copy = strdup (name);
   if (name_copy == NULL)
   {
@@ -88,15 +123,20 @@ static int uc_send_notification (const char *name)
     return (-1);
   }
 
-  n.severity = NOTIF_FAILURE;
-  strncpy (n.host, host, sizeof (n.host));
-  n.host[sizeof (n.host) - 1] = '\0';
+  /* Copy the associative members */
+  notification_init (&n, NOTIF_FAILURE, /* host = */ NULL,
+      host, plugin, plugin_instance, type, type_instance);
 
   sfree (name_copy);
   name_copy = host = plugin = plugin_instance = type = type_instance = NULL;
 
   pthread_mutex_lock (&cache_lock);
 
+  /*
+   * Set the time _after_ getting the lock because we don't know how long
+   * acquiring the lock takes and we will use this time later to decide
+   * whether or not the state is OKAY.
+   */
   n.time = time (NULL);
 
   status = c_avl_get (cache_tree, name, (void *) &ce);
@@ -203,7 +243,7 @@ int uc_check_timeout (void)
        ERROR ("uc_check_timeout: c_avl_remove (%s) failed.", keys[i]);
       }
       sfree (keys[i]);
-      sfree (ce);
+      cache_free (ce);
     }
     else /* (status > 0); ``service'' is interesting */
     {
@@ -309,8 +349,6 @@ int uc_update (const data_set_t *ds, const value_list_t *vl)
   else /* key is not found */
   {
     int i;
-    size_t ce_size = sizeof (cache_entry_t)
-      + ds->ds_num * (sizeof (counter_t) + sizeof (gauge_t));
     char *key;
     
     key = strdup (name);
@@ -321,22 +359,15 @@ int uc_update (const data_set_t *ds, const value_list_t *vl)
       return (-1);
     }
 
-    ce = (cache_entry_t *) malloc (ce_size);
+    ce = cache_alloc (ds->ds_num);
     if (ce == NULL)
     {
       pthread_mutex_unlock (&cache_lock);
-      ERROR ("uc_insert: malloc (%u) failed.", (unsigned int) ce_size);
+      ERROR ("uc_insert: cache_alloc (%i) failed.", ds->ds_num);
       return (-1);
     }
 
-    memset (ce, '\0', ce_size);
-
-    strncpy (ce->name, name, sizeof (ce->name));
-    ce->name[sizeof (ce->name) - 1] = '\0';
-
-    ce->values_num = ds->ds_num;
-    ce->values_gauge = (gauge_t *) (ce + 1);
-    ce->values_counter = (counter_t *) (ce->values_gauge + ce->values_num);
+    sstrncpy (ce->name, name, sizeof (ce->name));
 
     for (i = 0; i < ds->ds_num; i++)
     {
@@ -384,9 +415,10 @@ int uc_update (const data_set_t *ds, const value_list_t *vl)
     notification_t n;
     memset (&n, '\0', sizeof (n));
 
+    /* Copy the associative members */
+    NOTIFICATION_INIT_VL (&n, vl, ds);
+
     n.severity = NOTIF_OKAY;
-    strncpy (n.host, vl->host, sizeof (n.host));
-    n.host[sizeof (n.host) - 1] = '\0';
     n.time = vl->time;
 
     snprintf (n.message, sizeof (n.message),