X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Futils_cache.c;h=5598f687a7c77b8647d583ed326cb3148b6c061c;hb=5997c2158f5712e4b67be142726b6a627582cc78;hp=82567f33e01a86b638a572b21e5af35121f1d2a0;hpb=2fb1d3a320cba6abe16fe1e1d22ba085c465b6a8;p=collectd.git diff --git a/src/utils_cache.c b/src/utils_cache.c index 82567f33..5598f687 100644 --- a/src/utils_cache.c +++ b/src/utils_cache.c @@ -186,11 +186,13 @@ static int uc_insert (const data_set_t *ds, const value_list_t *vl, / CDTIME_T_TO_DOUBLE (vl->interval); ce->values_raw[i].absolute = vl->values[i].absolute; break; - + default: /* This shouldn't happen. */ ERROR ("uc_insert: Don't know how to handle data source type %i.", ds->ds[i].type); + sfree (key_copy); + cache_free (ce); return (-1); } /* switch (ds->ds[i].type) */ } /* for (i) */ @@ -296,7 +298,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 +323,6 @@ int uc_check_timeout (void) if (status != 0) { ERROR ("uc_check_timeout: parse_identifier_vl (\"%s\") failed.", keys[i]); - cache_free (ce); continue; } @@ -574,18 +581,6 @@ int uc_get_names (char ***ret_names, cdtime_t **ret_times, size_t *ret_number) size_t number = 0; size_t size_arrays = 0; - /* Increment size for the 2 arrays of values - * Because realloc is time consuming, it's better to - * realloc by blocks and not by units. - * To see the difference, set this value to 1. - * - * To change this value at compile time: - * ./configure CPPFLAGS="-DLISTVAL_INCREASE=102400" - */ -#ifndef LISTVAL_INCREASE -# define LISTVAL_INCREASE 1024 -#endif - int status = 0; if ((ret_names == NULL) || (ret_number == NULL)) @@ -593,47 +588,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; + /* c_avl_size does not return a number smaller than the number of elements + * returned by c_avl_iterator_next. */ + assert (number < size_arrays); + if (ret_times != NULL) - { - cdtime_t *tmp_times; - - if(number <= size_arrays) { - tmp_times = (cdtime_t *) realloc (times, sizeof (cdtime_t) * (size_arrays + LISTVAL_INCREASE)); - if (tmp_times == NULL) - { - status = -1; - break; - } - times = tmp_times; - } times[number] = value->last_time; - } - if(number <= size_arrays) { - temp = (char **) realloc (names, sizeof (char *) * (size_arrays + LISTVAL_INCREASE)); - if (temp == NULL) - { - status = -1; - break; - } - names = temp; - size_arrays += LISTVAL_INCREASE; - } names[number] = strdup (key); if (names[number] == NULL) { status = -1; break; } + number++; } /* while (c_avl_iterator_next) */ @@ -643,12 +638,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); } @@ -656,6 +652,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);