aboutsummaryrefslogtreecommitdiff
path: root/boehm-gc/linux_threads.c
diff options
context:
space:
mode:
Diffstat (limited to 'boehm-gc/linux_threads.c')
-rw-r--r--boehm-gc/linux_threads.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/boehm-gc/linux_threads.c b/boehm-gc/linux_threads.c
index 7958ed9bc17..b63dfb7fd7e 100644
--- a/boehm-gc/linux_threads.c
+++ b/boehm-gc/linux_threads.c
@@ -1271,6 +1271,17 @@ int WRAP_FUNC(pthread_join)(pthread_t thread, void **retval)
/* cant have been recycled by pthreads. */
UNLOCK();
result = REAL_FUNC(pthread_join)(thread, retval);
+# if defined (GC_FREEBSD_THREADS)
+ /* On FreeBSD, the wrapped pthread_join() sometimes returns (what
+ appears to be) a spurious EINTR which caused the test and real code
+ to gratuitously fail. Having looked at system pthread library source
+ code, I see how this return code may be generated. In one path of
+ code, pthread_join() just returns the errno setting of the thread
+ being joined. This does not match the POSIX specification or the
+ local man pages thus I have taken the liberty to catch this one
+ spurious return value properly conditionalized on GC_FREEBSD_THREADS. */
+ if (result == EINTR) result = 0;
+# endif
if (result == 0) {
LOCK();
/* Here the pthread thread id may have been recycled. */