aboutsummaryrefslogtreecommitdiff
path: root/src/common/compat_pthreads.c
diff options
context:
space:
mode:
authorDavid Goulet <dgoulet@ev0ke.net>2015-01-21 13:18:56 -0500
committerDavid Goulet <dgoulet@ev0ke.net>2015-01-21 14:29:12 -0500
commitd684dbb0c76c4de0b21fabee99fc08833249bd87 (patch)
tree62f86dc48ab8f3df15273384906538f981e8bf6e /src/common/compat_pthreads.c
parent3c8dabf69aa950c2df49f48aebbe02aac5b519f3 (diff)
downloadtor-d684dbb0c76c4de0b21fabee99fc08833249bd87.tar.gz
tor-d684dbb0c76c4de0b21fabee99fc08833249bd87.zip
Support monotonic time for pthread_cond_timedwait
This is to avoid that the pthread_cond_timedwait() is not affected by time adjustment which could make the waiting period very long or very short which is not what we want in any cases. Signed-off-by: David Goulet <dgoulet@ev0ke.net>
Diffstat (limited to 'src/common/compat_pthreads.c')
-rw-r--r--src/common/compat_pthreads.c30
1 files changed, 28 insertions, 2 deletions
diff --git a/src/common/compat_pthreads.c b/src/common/compat_pthreads.c
index c217c5145b..e1d4b0e79b 100644
--- a/src/common/compat_pthreads.c
+++ b/src/common/compat_pthreads.c
@@ -6,6 +6,7 @@
#include "orconfig.h"
#include <pthread.h>
#include <signal.h>
+#include <time.h>
#include "compat.h"
#include "torlog.h"
@@ -169,8 +170,23 @@ tor_get_thread_id(void)
int
tor_cond_init(tor_cond_t *cond)
{
+ pthread_condattr_t condattr;
+
memset(cond, 0, sizeof(tor_cond_t));
- if (pthread_cond_init(&cond->cond, NULL)) {
+ /* Default condition attribute. Might be used if clock monotonic is
+ * available else this won't affect anything. */
+ if (pthread_condattr_init(&condattr)) {
+ return -1;
+ }
+
+#if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
+ /* Use monotonic time so when we timedwait() on it, any clock adjustment
+ * won't affect the timeout value. */
+ if (pthread_condattr_setclock(&condattr, CLOCK_MONOTONIC)) {
+ return -1;
+ }
+#endif
+ if (pthread_cond_init(&cond->cond, &condattr)) {
return -1;
}
return 0;
@@ -209,12 +225,22 @@ tor_cond_wait(tor_cond_t *cond, tor_mutex_t *mutex, const struct timeval *tv)
return r ? -1 : 0;
}
} else {
- struct timespec ts;
struct timeval tvnow, tvsum;
+ struct timespec ts;
while (1) {
+#if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
+ if (clock_gettime(CLOCK_MONOTONIC, &ts) < 0) {
+ return -1;
+ }
+ tvnow.tv_sec = ts.tv_sec;
+ tvnow.tv_usec = ts.tv_nsec / 1000;
+ timeradd(tv, &tvnow, &tvsum);
+#else
if (gettimeofday(&tvnow, NULL) < 0)
return -1;
timeradd(tv, &tvnow, &tvsum);
+#endif /* HAVE_CLOCK_GETTIME, CLOCK_MONOTONIC */
+
ts.tv_sec = tvsum.tv_sec;
ts.tv_nsec = tvsum.tv_usec * 1000;