[master] e5e545f9f OSX returns EINVAL for pthread_cond_timedwait(2) timestamps in the past.

Poul-Henning Kamp phk at FreeBSD.org
Mon Jan 20 13:33:06 UTC 2020


commit e5e545f9fe14b4bfd4003c26403d80645c73385a
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Mon Jan 20 13:30:06 2020 +0000

    OSX returns EINVAL for pthread_cond_timedwait(2) timestamps in the past.
    
    Fixes   #1853

diff --git a/bin/varnishd/cache/cache_lck.c b/bin/varnishd/cache/cache_lck.c
index 3d7dd74d8..c0bb98bb3 100644
--- a/bin/varnishd/cache/cache_lck.c
+++ b/bin/varnishd/cache/cache_lck.c
@@ -40,6 +40,10 @@
 #include <stdlib.h>
 #include <stdio.h>
 
+#if defined (__APPLE__)
+#    include "vtim.h"
+#endif
+
 #include "VSC_lck.h"
 
 struct ilck {
@@ -214,6 +218,19 @@ Lck_CondWait(pthread_cond_t *cond, struct lock *lck, vtim_real when)
 		ts.tv_sec = (long)t;
 		assert(ts.tv_nsec >= 0 && ts.tv_nsec < 999999999);
 		errno = pthread_cond_timedwait(cond, &ilck->mtx, &ts);
+#if defined (__APPLE__)
+		if (errno == EINVAL && when > VTIM_real()) {
+			/*
+			 * Most kernels treat this as honest error,
+			 * recognizing that a thread has no way to
+			 * prevent being descheduled between a user-
+			 * land check of the timestamp, and getting
+			 * the timestamp into the kernel before it
+			 * expires.  OS/X on the other hand...
+			 */
+			errno = ETIMEDOUT;
+		}
+#endif
 		assert(errno == 0 ||
 		    errno == ETIMEDOUT ||
 		    errno == EINTR);


More information about the varnish-commit mailing list