summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: aabd76e)
raw | patch | inline | side by side (parent: aabd76e)
author | oetiker <oetiker@a5681a0c-68f1-0310-ab6d-d61299d08faa> | |
Mon, 20 Apr 2009 06:48:01 +0000 (06:48 +0000) | ||
committer | oetiker <oetiker@a5681a0c-68f1-0310-ab6d-d61299d08faa> | |
Mon, 20 Apr 2009 06:48:01 +0000 (06:48 +0000) |
This simplifies the code that manages some of the dynamic structures
inside rrdcached.
A few data types have been changed to size_t.
-- kevin
git-svn-id: svn://svn.oetiker.ch/rrdtool/trunk@1796 a5681a0c-68f1-0310-ab6d-d61299d08faa
inside rrdcached.
A few data types have been changed to size_t.
-- kevin
git-svn-id: svn://svn.oetiker.ch/rrdtool/trunk@1796 a5681a0c-68f1-0310-ab6d-d61299d08faa
program/doc/Makefile.am | patch | blob | history | |
program/doc/librrd.pod | [new file with mode: 0644] | patch | blob |
program/src/librrd.sym.in.in | patch | blob | history | |
program/src/rrd.h | patch | blob | history | |
program/src/rrd_daemon.c | patch | blob | history | |
program/src/rrd_utils.c | patch | blob | history |
index f5f2cb15de49da63525c83dd44254056cb320216..74a54552fd4b9bb50df81f100bb0d2a4f52d0f94 100644 (file)
--- a/program/doc/Makefile.am
+++ b/program/doc/Makefile.am
rpntutorial.pod rrdfirst.pod rrdgraph_rpn.pod rrdtool.pod rrdcached.pod \
rrd-beginners.pod rrdinfo.pod rrdtune.pod rrdbuild.pod rrdflush.pod \
rrdcgi.pod rrdgraph.pod rrdlast.pod rrdlastupdate.pod \
- rrdcreate.pod rrdgraph_data.pod rrdresize.pod rrdtutorial.pod
+ rrdcreate.pod rrdgraph_data.pod rrdresize.pod rrdtutorial.pod librrd.pod
if BUILD_LIBDBI
POD += rrdgraph_libdbi.pod
diff --git a/program/doc/librrd.pod b/program/doc/librrd.pod
--- /dev/null
+++ b/program/doc/librrd.pod
@@ -0,0 +1,61 @@
+=pod
+
+=head1 NAME
+
+librrd - RRD library functions
+
+=head1 DESCRIPTION
+
+B<librrd> contains most of the functionality in B<RRDTool>. The command
+line utilities and language bindings are often just wrappers around the
+code contained in B<librrd>.
+
+This manual page documents the B<librrd> API.
+
+B<NOTE:> This document is a work in progress, and should be considered
+incomplete as long as this warning persists. For more information about
+the B<librrd> functions, always consult the source code.
+
+=head1 UTILITY FUNCTIONS
+
+=over
+
+=item B<rrd_random()>
+
+Generates random numbers just like random(). This further ensures that
+the random number generator is seeded exactly once per process.
+
+=item B<rrd_add_ptr(void ***dest, size_t *dest_size, void *src)>
+
+Dynamically resize the array pointed to by C<dest>. C<dest_size> is a
+pointer to the current size of C<dest>. Upon successful realloc(), the
+C<dest_size> is incremented by 1 and the C<src> pointer is stored at the
+end of the new C<dest>. Returns 1 on success, 0 on failure.
+
+ type **arr = NULL;
+ type *elem = "whatever";
+ size_t arr_size = 0;
+ if (!rrd_add_ptr(&arr, &arr_size, elem))
+ handle_failure();
+
+=item B<rrd_add_strdup(char ***dest, size_t *dest_size, char *src)>
+
+Like C<rrd_add_ptr>, except adds a C<strdup> of the source string.
+
+ char **arr = NULL;
+ size_t arr_size = NULL;
+ char *str = "example text";
+ if (!rrd_add_strdup(&arr, &arr_size, str))
+ handle_failure();
+
+=item B<rrd_free_ptrs(void ***src, size_t *cnt)>
+
+Free an array of pointers allocated by C<rrd_add_ptr> or
+C<rrd_add_strdup>. Also frees the array pointer itself. On return, the
+source pointer will be NULL and the count will be zero.
+
+ /* created as above */
+ rrd_free_ptrs(&arr, &arr_size);
+ /* here, arr == NULL && arr_size == 0 */
+
+=back
index 0a7a699dca9da1713ecbf574597957b5b8122c9e..f947fe530068eff6d6c00d1cbce482e4684dcc23 100644 (file)
+rrd_add_ptr
+rrd_add_strdup
rrd_clear_error
rrd_close
rrd_cmd_flush
rrd_first_r
rrd_free
rrd_free_context
+rrd_free_ptrs
rrd_freemem
rrd_get_context
rrd_get_error
diff --git a/program/src/rrd.h b/program/src/rrd.h
index fd506d94e9c4533782d75e0212eb3e6775456a3d..0227ed4a00c2426facc4f2493d833d6b28ad869f 100644 (file)
--- a/program/src/rrd.h
+++ b/program/src/rrd.h
long rrd_random(void);
+ int rrd_add_ptr(void ***dest, size_t *dest_size, void *src);
+ int rrd_add_strdup(char ***dest, size_t *dest_size, char *src);
+ void rrd_free_ptrs(void ***src, size_t *cnt);
+
/*
* The following functions are _internal_ functions needed to read the raw RRD
* files. Since they are _internal_ they may change with the file format and
index 7a7ae88696a9add76a304c792d9d6d88a601d87d..53904a331357b2d0a745bb625249191cb26f28c4 100644 (file)
--- a/program/src/rrd_daemon.c
+++ b/program/src/rrd_daemon.c
{
char *file;
char **values;
- int values_num;
+ size_t values_num;
time_t last_flush_time;
time_t last_update_stamp;
#define CI_FLAGS_IN_TREE (1<<0)
static int config_write_base_only = 0;
static listen_socket_t **config_listen_address_list = NULL;
-static int config_listen_address_list_len = 0;
+static size_t config_listen_address_list_len = 0;
static uint64_t stats_queue_length = 0;
static uint64_t stats_updates_received = 0;
remove_from_queue(ci);
- for (int i=0; i < ci->values_num; i++)
+ for (size_t i=0; i < ci->values_num; i++)
free(ci->values[i]);
free (ci->values);
else if (((cfd->now - ci->last_flush_time) >= config_flush_interval)
&& (ci->values_num <= 0))
{
- char **temp;
-
- temp = (char **) rrd_realloc (cfd->keys,
- sizeof (char *) * (cfd->keys_num + 1));
- if (temp == NULL)
+ assert ((char *) key == ci->file);
+ if (!rrd_add_ptr((void ***)&cfd->keys, &cfd->keys_num, (void *)key))
{
- RRDD_LOG (LOG_ERR, "tree_callback_flush: realloc failed.");
+ RRDD_LOG (LOG_ERR, "tree_callback_flush: rrd_add_ptrs failed.");
return (FALSE);
}
- cfd->keys = temp;
- /* Make really sure this points to the _same_ place */
- assert ((char *) key == ci->file);
- cfd->keys[cfd->keys_num] = (char *) key;
- cfd->keys_num++;
}
return (FALSE);
cache_item_t *ci;
char *file;
char **values;
- int values_num;
+ size_t values_num;
int status;
- int i;
/* Now, check if there's something to store away. If not, wait until
* something comes in. if we are shutting down, do not wait around. */
pthread_mutex_unlock (&cache_lock);
rrd_clear_error ();
- status = rrd_update_r (file, NULL, values_num, (void *) values);
+ status = rrd_update_r (file, NULL, (int) values_num, (void *) values);
if (status != 0)
{
RRDD_LOG (LOG_NOTICE, "queue_thread_main: "
journal_write("wrote", file);
pthread_cond_broadcast(&ci->flushed);
- for (i = 0; i < values_num; i++)
- free (values[i]);
-
- free(values);
+ rrd_free_ptrs((void ***) &values, &values_num);
free(file);
if (status == 0)
return send_response(sock, RESP_ERR, "%s\n", rrd_strerror(ENOENT));
}
- for (int i=0; i < ci->values_num; i++)
+ for (size_t i=0; i < ci->values_num; i++)
add_response_info(sock, "%s\n", ci->values[i]);
pthread_mutex_unlock(&cache_lock);
while (buffer_size > 0)
{
- char **temp;
char *value;
time_t stamp;
char *eostamp;
else
ci->last_update_stamp = stamp;
- temp = (char **) rrd_realloc (ci->values,
- sizeof (char *) * (ci->values_num + 1));
- if (temp == NULL)
- {
- RRDD_LOG (LOG_ERR, "handle_request_update: realloc failed.");
- continue;
- }
- ci->values = temp;
-
- ci->values[ci->values_num] = strdup (value);
- if (ci->values[ci->values_num] == NULL)
+ if (!rrd_add_strdup(&ci->values, &ci->values_num, value))
{
- RRDD_LOG (LOG_ERR, "handle_request_update: strdup failed.");
+ RRDD_LOG (LOG_ERR, "handle_request_update: rrd_add_strdup failed.");
continue;
}
- ci->values_num++;
values_num++;
}
*/
static int handle_request_wrote (HANDLER_PROTO) /* {{{ */
{
- int i;
cache_item_t *ci;
const char *file = buffer;
}
if (ci->values)
- {
- for (i=0; i < ci->values_num; i++)
- free(ci->values[i]);
-
- free(ci->values);
- }
+ rrd_free_ptrs((void ***) &ci->values, &ci->values_num);
wipe_ci_values(ci, now);
remove_from_queue(ci);
/* open all the listen sockets */
if (config_listen_address_list_len > 0)
{
- for (int i = 0; i < config_listen_address_list_len; i++)
- {
+ for (size_t i = 0; i < config_listen_address_list_len; i++)
open_listen_socket (config_listen_address_list[i]);
- free_listen_socket (config_listen_address_list[i]);
- }
- free(config_listen_address_list);
+ rrd_free_ptrs((void ***) &config_listen_address_list,
+ &config_listen_address_list_len);
}
else
{
case 'L':
case 'l':
{
- listen_socket_t **temp;
listen_socket_t *new;
new = malloc(sizeof(listen_socket_t));
}
memset(new, 0, sizeof(listen_socket_t));
- temp = (listen_socket_t **) rrd_realloc (config_listen_address_list,
- sizeof (listen_socket_t *) * (config_listen_address_list_len + 1));
- if (temp == NULL)
- {
- fprintf (stderr, "read_options: realloc failed.\n");
- return (2);
- }
- config_listen_address_list = temp;
-
strncpy(new->addr, optarg, sizeof(new->addr)-1);
new->privilege = (option == 'l') ? PRIV_HIGH : PRIV_LOW;
- temp[config_listen_address_list_len] = new;
- config_listen_address_list_len++;
+ if (!rrd_add_ptr((void ***)&config_listen_address_list,
+ &config_listen_address_list_len, new))
+ {
+ fprintf(stderr, "read_options: rrd_add_ptr failed.\n");
+ return (2);
+ }
}
break;
index 39d2aca1601cac61e5507047fcf0802f4af5163a..9ac3e8ab7536e00771bf13afcc9fccbe88290689 100644 (file)
--- a/program/src/rrd_utils.c
+++ b/program/src/rrd_utils.c
#include "rrd_tool.h"
#include <stdlib.h>
+#include <assert.h>
#ifdef WIN32
# define random() rand()
return random();
}
+
+/* rrd_add_ptr: add a pointer to a dynamically sized array of pointers,
+ * realloc as necessary. returns 1 on success, 0 on failure.
+ */
+
+int rrd_add_ptr(void ***dest, size_t *dest_size, void *src)
+{
+ void **temp;
+
+ assert(dest != NULL);
+
+ temp = (void **) rrd_realloc(*dest, (*dest_size+1) * sizeof(*dest));
+ if (!temp)
+ return 0;
+
+ *dest = temp;
+ temp[*dest_size] = src;
+ (*dest_size)++;
+
+ return 1;
+}
+
+/* like rrd_add_ptr, but calls strdup() on a string first. */
+int rrd_add_strdup(char ***dest, size_t *dest_size, char *src)
+{
+ char *dup_src;
+ int add_ok;
+
+ assert(dest != NULL);
+ assert(src != NULL);
+
+ dup_src = strdup(src);
+ if (!dup_src)
+ return 0;
+
+ add_ok = rrd_add_ptr((void ***)dest, dest_size, (void *)dup_src);
+ if (!add_ok)
+ free(dup_src);
+
+ return add_ok;
+}
+
+void rrd_free_ptrs(void ***src, size_t *cnt)
+{
+ void **sp;
+
+ assert(src != NULL);
+ sp = *src;
+
+ if (sp == NULL)
+ return;
+
+ while (*cnt > 0) {
+ (*cnt)--;
+ free(sp[*cnt]);
+ }
+
+ free (sp);
+ *src = NULL;
+}