summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 82e69ea)
raw | patch | inline | side by side (parent: 82e69ea)
author | oetiker <oetiker@a5681a0c-68f1-0310-ab6d-d61299d08faa> | |
Fri, 26 Sep 2008 05:10:25 +0000 (05:10 +0000) | ||
committer | oetiker <oetiker@a5681a0c-68f1-0310-ab6d-d61299d08faa> | |
Fri, 26 Sep 2008 05:10:25 +0000 (05:10 +0000) |
RRD before returning to the user. Before, it returned when the update was
"dequeued"; updates were not necessarily on disk.
Also, for new nodes, the cache_lock is not held while we are setting up
the new node. We don't want to be holding the lock if the stat() blocks.
-- kevin brintnal
git-svn-id: svn://svn.oetiker.ch/rrdtool/trunk@1527 a5681a0c-68f1-0310-ab6d-d61299d08faa
"dequeued"; updates were not necessarily on disk.
Also, for new nodes, the cache_lock is not held while we are setting up
the new node. We don't want to be holding the lock if the stat() blocks.
-- kevin brintnal
git-svn-id: svn://svn.oetiker.ch/rrdtool/trunk@1527 a5681a0c-68f1-0310-ab6d-d61299d08faa
program/doc/rrdcached.pod | patch | blob | history | |
program/doc/rrdflush.pod | patch | blob | history | |
program/src/rrd_daemon.c | patch | blob | history |
index 3505728b08b1644e64c0960501275ae537f648cd..bf289c592d7aff9e5d195104dcf39e0d2bb55c53 100644 (file)
from the RRDE<nbsp>files. To get around this, the daemon provides the "flush
command" to flush specific files. This means that the file is inserted at the
B<head> of the update queue or moved there if it is already enqueued. The flush
-command will return after the update thread has dequeued the file, so there is
-a good chance that the file has been updated by the time the client receives
-the response from the daemon, but there is no guarantee.
+command will return only after the file's pending updates have been written
+to disk.
+------+ +------+ +------+
! head ! ! root ! ! tail !
index a59382124973d9646757a8756cc10a67c30e87e4..514bd35fe95a6f19147591443c4ab58cdb095390 100644 (file)
--- a/program/doc/rrdflush.pod
+++ b/program/doc/rrdflush.pod
The B<flush> function connects to L<rrdcached>, the RRD caching daemon, and
issues a "flush" command for the given file. The daemon will put this file to
the head of the update queue so it is written "soon". The status will be
-returned after the node has been B<dequeued> by the update thread. By the time
-execution of this command ends it is very likely that the update thread has
-just updated the requested file, though this is not guaranteed.
+returned only after the file's pending updates have been written to disk.
=over 8
index c438028134ed5c27b2f89edf8853c529d1c1ad89..1c02a495cac793fe21f73e93f9af65ba47def510 100644 (file)
--- a/program/src/rrd_daemon.c
+++ b/program/src/rrd_daemon.c
#define CI_FLAGS_IN_TREE (1<<0)
#define CI_FLAGS_IN_QUEUE (1<<1)
int flags;
-
+ pthread_cond_t flushed;
cache_item_t *next;
};
static pthread_mutex_t cache_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cache_cond = PTHREAD_COND_INITIALIZER;
-static pthread_cond_t flush_cond = PTHREAD_COND_INITIALIZER;
-
static int config_write_interval = 300;
static int config_write_jitter = 0;
static int config_flush_interval = 3600;
}
journal_write("wrote", file);
+ pthread_cond_broadcast(&ci->flushed);
for (i = 0; i < values_num; i++)
free (values[i]);
}
pthread_mutex_lock (&cache_lock);
- pthread_cond_broadcast (&flush_cond);
/* We're about to shut down, so lets flush the entire tree. */
if ((do_shutdown != 0) && (cache_queue_head == NULL))
enqueue_cache_item (ci, HEAD);
pthread_cond_signal (&cache_cond);
- while ((ci->flags & CI_FLAGS_IN_QUEUE) != 0)
- {
- ci = NULL;
-
- pthread_cond_wait (&flush_cond, &cache_lock);
-
- ci = g_tree_lookup (cache_tree, filename);
- if (ci == NULL)
- {
- RRDD_LOG (LOG_ERR, "flush_file: Tree node went away "
- "while waiting for flush.");
- pthread_mutex_unlock (&cache_lock);
- return (-1);
- }
- }
+ pthread_cond_wait(&ci->flushed, &cache_lock);
+ pthread_mutex_unlock(&cache_lock);
- pthread_mutex_unlock (&cache_lock);
return (0);
} /* }}} int flush_file */
pthread_mutex_unlock(&stats_lock);
pthread_mutex_lock (&cache_lock);
-
ci = g_tree_lookup (cache_tree, file);
+
if (ci == NULL) /* {{{ */
{
struct stat statbuf;
+ /* don't hold the lock while we setup; stat(2) might block */
+ pthread_mutex_unlock(&cache_lock);
+
memset (&statbuf, 0, sizeof (statbuf));
status = stat (file, &statbuf);
if (status != 0)
{
- pthread_mutex_unlock (&cache_lock);
RRDD_LOG (LOG_NOTICE, "handle_request_update: stat (%s) failed.", file);
status = errno;
}
if (!S_ISREG (statbuf.st_mode))
{
- pthread_mutex_unlock (&cache_lock);
-
snprintf (answer, sizeof (answer), "-1 Not a regular file: %s\n", file);
RRDD_UPDATE_SEND;
return (0);
}
if (access(file, R_OK|W_OK) != 0)
{
- pthread_mutex_unlock (&cache_lock);
-
snprintf (answer, sizeof (answer), "-1 Cannot read/write %s: %s\n",
file, rrd_strerror(errno));
RRDD_UPDATE_SEND;
ci = (cache_item_t *) malloc (sizeof (cache_item_t));
if (ci == NULL)
{
- pthread_mutex_unlock (&cache_lock);
RRDD_LOG (LOG_ERR, "handle_request_update: malloc failed.");
strncpy (answer, "-1 malloc failed.\n", sizeof (answer));
ci->file = strdup (file);
if (ci->file == NULL)
{
- pthread_mutex_unlock (&cache_lock);
free (ci);
RRDD_LOG (LOG_ERR, "handle_request_update: strdup failed.");
_wipe_ci_values(ci, now);
ci->flags = CI_FLAGS_IN_TREE;
+ pthread_mutex_lock(&cache_lock);
g_tree_insert (cache_tree, (void *) ci->file, (void *) ci);
} /* }}} */
assert (ci != NULL);