summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Körner <christian_koerner@web.de>2015-10-16 14:25:22 +0200
committerMax Kellermann <max@musicpd.org>2016-09-19 11:21:21 +0200
commit8bbfb5cda12e105460c1e2bf22066873ecc29b0f (patch)
treefc5a0abbbd12fdc651c4d84974b04ed3d3793e03
parent1e17d5b1cc8614fc4316d5b4c2668b6848ce67d4 (diff)
thread/PosixCond: fix timed_wait
pthread_cond_timedwait() in PosixCond.hxx:timed_wait(PosixMutex...) returns EINVAL, if ts.tv_nsec >= 1E9. In this case, it returns to early. Find attached a patch which fixes this. I chose a compare-subtraction method to keep ts.tv_nsec below 1E9. Another option would be ts.tv_sec += ts.tv_nsec / 1000000000; ts.tv_nsec %= 1000000000; But I guess this takes more time on some ARM processors, which don't support hardware division.
-rw-r--r--src/thread/PosixCond.hxx5
1 files changed, 5 insertions, 0 deletions
diff --git a/src/thread/PosixCond.hxx b/src/thread/PosixCond.hxx
index 73dbe0218..4e1988ece 100644
--- a/src/thread/PosixCond.hxx
+++ b/src/thread/PosixCond.hxx
@@ -79,6 +79,11 @@ public:
struct timespec ts;
ts.tv_sec = now.tv_sec + timeout_ms / 1000;
ts.tv_nsec = (now.tv_usec + (timeout_ms % 1000) * 1000) * 1000;
+ // Keep tv_nsec < 1E9 to prevent return of EINVAL
+ if (ts.tv_nsec >= 1000000000) {
+ ts.tv_nsec -= 1000000000;
+ ts.tv_sec++;
+ }
return pthread_cond_timedwait(&cond, &mutex.mutex, &ts) == 0;
}