[master] a53079e38 Change the OS/X workaround for pthread_cond_timedwait() returning EINVAL

Poul-Henning Kamp phk at FreeBSD.org
Tue Mar 29 18:06:07 UTC 2022


commit a53079e385abcfba4bfe88414a52e94c1dc444c5
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Tue Mar 29 18:04:45 2022 +0000

    Change the OS/X workaround for pthread_cond_timedwait() returning EINVAL

diff --git a/bin/varnishd/cache/cache_lck.c b/bin/varnishd/cache/cache_lck.c
index 827a12343..6615897eb 100644
--- a/bin/varnishd/cache/cache_lck.c
+++ b/bin/varnishd/cache/cache_lck.c
@@ -229,34 +229,6 @@ Lck_CondWaitUntil(pthread_cond_t *cond, struct lock *lck, vtim_real when)
 	struct ilck *ilck;
 	struct timespec ts;
 
-#if defined (__APPLE__)
-	/*
-	 * I hate woo-doo programming in all it's forms and all it's
-	 * manifestations, but for reasons I utterly fail to isolate
-	 * yielding here is stops OSX from throwing a EINVAL to the
-	 * pthread_cond_wait(3) call.
-	 *
-	 * I have tried very hard to determine if any of the three
-	 * arguments are in fact invalid, and found nothing which
-	 * even hints that it might be the case, and with high probability
-	 * repeating the failed call with the exact same arguments
-	 * will succeed.
-	 *
-	 * If you want to dive into this you can trigger the situation
-	 * approx 30% of the time with:
-	 *
-	 *	cd .../vmods && make -j check
-	 *
-	 * Env:
-	 *	Darwin Kernel Version 20.5.0:
-	 *	Sat May  8 05:10:31 PDT 2021;
-	 *	root:xnu-7195.121.3~9/RELEASE_ARM64_T8101 arm64
-	 *
-	 * 20211027 /phk
-	 */
-	pthread_yield_np();
-#endif
-
 	AN(lck);
 	CAST_OBJ_NOTNULL(ilck, lck->priv, ILCK_MAGIC);
 	AN(ilck->held);
@@ -270,6 +242,34 @@ Lck_CondWaitUntil(pthread_cond_t *cond, struct lock *lck, vtim_real when)
 		ts = VTIM_timespec(when);
 		assert(ts.tv_nsec >= 0 && ts.tv_nsec <= 999999999);
 		errno = pthread_cond_timedwait(cond, &ilck->mtx, &ts);
+#if defined (__APPLE__)
+		/*
+		 * I hate woo-doo programming in all it's forms and all it's
+		 * manifestations, but for reasons I utterly fail to isolate,
+		 * OSX sometimes throws an EINVAL.
+		 *
+		 * I have tried very hard to determine if any of the three
+		 * arguments are in fact invalid, and found nothing which
+		 * even hints that it might be the case.
+		 *
+		 * So far I have yet to see a failure if the exact same
+		 * call is repeated after a very short sleep.
+		 *
+		 * Calling pthread_yield_np() instead of sleaping /mostly/
+		 * works as well, but still fails sometimes.
+		 *
+		 * Env:
+		 *	Darwin Kernel Version 20.5.0:
+		 *	Sat May  8 05:10:31 PDT 2021;
+		 *	root:xnu-7195.121.3~9/RELEASE_ARM64_T8101 arm64
+		 *
+		 * 20220329 /phk
+		 */
+		if (errno == EINVAL) {
+			usleep(100);
+			errno = pthread_cond_timedwait(cond, &ilck->mtx, &ts);
+		}
+#endif
 		assert(errno == 0 ||
 		    errno == ETIMEDOUT ||
 		    errno == EINTR);


More information about the varnish-commit mailing list