X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Futils_cache.c;h=910e30b29cbec6d99974eae30bb0f9418bb80a16;hb=1a0ffe992fa7a970346fafb5f688fce5ee6f22ee;hp=dd5bcb59ffc9833b2a92341a085e32d526e9e812;hpb=6bd4bf7b21f84746010792b885b9b71791dccb79;p=collectd.git diff --git a/src/utils_cache.c b/src/utils_cache.c index dd5bcb59..910e30b2 100644 --- a/src/utils_cache.c +++ b/src/utils_cache.c @@ -191,6 +191,7 @@ static int uc_insert (const data_set_t *ds, const value_list_t *vl, /* This shouldn't happen. */ ERROR ("uc_insert: Don't know how to handle data source type %i.", ds->ds[i].type); + sfree (key_copy); return (-1); } /* switch (ds->ds[i].type) */ } /* for (i) */ @@ -296,7 +297,13 @@ int uc_check_timeout (void) pthread_mutex_unlock (&cache_lock); if (keys_len == 0) + { + /* realloc() may have been called for these. */ + sfree (keys); + sfree (keys_time); + sfree (keys_interval); return (0); + } /* Call the "missing" callback for each value. Do this before removing the * value from the cache, so that callbacks can still access the data stored, @@ -315,7 +322,6 @@ int uc_check_timeout (void) if (status != 0) { ERROR ("uc_check_timeout: parse_identifier_vl (\"%s\") failed.", keys[i]); - cache_free (ce); continue; } @@ -572,6 +578,7 @@ int uc_get_names (char ***ret_names, cdtime_t **ret_times, size_t *ret_number) char **names = NULL; cdtime_t *times = NULL; size_t number = 0; + size_t size_arrays = 0; int status = 0; @@ -580,42 +587,47 @@ int uc_get_names (char ***ret_names, cdtime_t **ret_times, size_t *ret_number) pthread_mutex_lock (&cache_lock); + size_arrays = (size_t) c_avl_size (cache_tree); + if (size_arrays < 1) + { + /* Handle the "no values" case here, to avoid the error message when + * calloc() returns NULL. */ + pthread_mutex_unlock (&cache_lock); + return (0); + } + + names = calloc (size_arrays, sizeof (*names)); + times = calloc (size_arrays, sizeof (*times)); + if ((names == NULL) || (times == NULL)) + { + ERROR ("uc_get_names: calloc failed."); + sfree (names); + sfree (times); + pthread_mutex_unlock (&cache_lock); + return (ENOMEM); + } + iter = c_avl_get_iterator (cache_tree); while (c_avl_iterator_next (iter, (void *) &key, (void *) &value) == 0) { - char **temp; - /* remove missing values when list values */ if (value->state == STATE_MISSING) continue; - if (ret_times != NULL) - { - cdtime_t *tmp_times; + /* c_avl_size does not return a number smaller than the number of elements + * returned by c_avl_iterator_next. */ + assert (number < size_arrays); - tmp_times = (cdtime_t *) realloc (times, sizeof (cdtime_t) * (number + 1)); - if (tmp_times == NULL) - { - status = -1; - break; - } - times = tmp_times; + if (ret_times != NULL) times[number] = value->last_time; - } - temp = (char **) realloc (names, sizeof (char *) * (number + 1)); - if (temp == NULL) - { - status = -1; - break; - } - names = temp; names[number] = strdup (key); if (names[number] == NULL) { status = -1; break; } + number++; } /* while (c_avl_iterator_next) */ @@ -625,12 +637,13 @@ int uc_get_names (char ***ret_names, cdtime_t **ret_times, size_t *ret_number) if (status != 0) { size_t i; - + for (i = 0; i < number; i++) { sfree (names[i]); } sfree (names); + sfree (times); return (-1); } @@ -638,6 +651,8 @@ int uc_get_names (char ***ret_names, cdtime_t **ret_times, size_t *ret_number) *ret_names = names; if (ret_times != NULL) *ret_times = times; + else + sfree (times); *ret_number = number; return (0);