From dbe1a7d29fe1758380c50644e8b9cba3e618a25f Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Sat, 6 Feb 2010 16:10:33 +0100 Subject: [PATCH] Bugfix: correctly handle spurious wakeups in pthread_cond_timedwait This fixes problems storing data in rrd files on NetBSD 5.0 with more than one CPU. Signed-off-by: Florian Forster --- src/plugin.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/plugin.c b/src/plugin.c index 11a0ef6e..c163ca7d 100644 --- a/src/plugin.c +++ b/src/plugin.c @@ -302,6 +302,13 @@ static int plugin_load_file (char *file) return (0); } +static _Bool timeout_reached(struct timespec timeout) +{ + struct timeval now; + gettimeofday(&now, NULL); + return (now.tv_sec >= timeout.tv_sec && now.tv_usec >= (timeout.tv_nsec / 1000)); +} + static void *plugin_read_thread (void __attribute__((unused)) *args) { while (read_loop != 0) @@ -310,6 +317,7 @@ static void *plugin_read_thread (void __attribute__((unused)) *args) struct timeval now; int status; int rf_type; + int rc; /* Get the read function that needs to be read next. */ rf = c_head_get_root (read_heap); @@ -345,8 +353,16 @@ static void *plugin_read_thread (void __attribute__((unused)) *args) /* sleep until this entry is due, * using pthread_cond_timedwait */ pthread_mutex_lock (&read_lock); - pthread_cond_timedwait (&read_cond, &read_lock, + /* In pthread_cond_timedwait, spurious wakeups are possible + * (and really happen, at least on NetBSD with > 1 CPU), thus + * we need to re-evaluate the condition every time + * pthread_cond_timedwait returns. */ + rc = 0; + while (!timeout_reached(rf->rf_next_read) && rc == 0) { + rc = pthread_cond_timedwait (&read_cond, &read_lock, &rf->rf_next_read); + } + /* Must hold `real_lock' when accessing `rf->rf_type'. */ rf_type = rf->rf_type; pthread_mutex_unlock (&read_lock); -- 2.30.2