From 1a0c94c8e109fc19a79579bca8924d87bf2a61fa Mon Sep 17 00:00:00 2001 From: Ivan Maidanski Date: Fri, 13 Oct 2023 09:19:08 +0300 Subject: [PATCH] Workaround pthread_rwlock_init() fail with EBUSY on OS X (fix of commit 3bfb499f3) Issue #473 (bdwgc). * pthread_support.c [CAN_HANDLE_FORK && USE_PTHREAD_LOCKS && !GC_WIN32_THREADS && USE_RWLOCK] (fork_child_proc): Update comment. * pthread_support.c [CAN_HANDLE_FORK && USE_PTHREAD_LOCKS && !GC_WIN32_THREADS && USE_RWLOCK && DARWIN] (fork_child_proc): Do not call pthread_rwlock_init(); reset GC_allocate_ml to PTHREAD_RWLOCK_INITIALIZER instead; add comment. --- pthread_support.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/pthread_support.c b/pthread_support.c index d5d955033..ee38162ca 100644 --- a/pthread_support.c +++ b/pthread_support.c @@ -1443,13 +1443,22 @@ GC_INNER void GC_wait_for_gc_completion(GC_bool wait_for_all) GC_ASSERT(I_DONT_HOLD_LOCK()); /* Reinitialize the mutex. It should be safe since we are */ /* running this in the child which only inherits a single thread. */ - /* mutex_destroy() may return EBUSY, which makes no sense, but */ - /* that is the reason for the need of the reinitialization. */ + /* pthread_mutex_destroy() and pthread_rwlock_destroy() may */ + /* return EBUSY, which makes no sense, but that is the reason for */ + /* the need of the reinitialization. */ /* Note: excluded for Cygwin as does not seem to be needed. */ # ifdef USE_RWLOCK (void)pthread_rwlock_destroy(&GC_allocate_ml); - if (pthread_rwlock_init(&GC_allocate_ml, NULL) != 0) - ABORT("pthread_rwlock_init failed (in child)"); +# ifdef DARWIN + /* A workaround for pthread_rwlock_init() fail with EBUSY. */ + { + pthread_rwlock_t rwlock_local = PTHREAD_RWLOCK_INITIALIZER; + BCOPY(&rwlock_local, &GC_allocate_ml, sizeof(GC_allocate_ml)); + } +# else + if (pthread_rwlock_init(&GC_allocate_ml, NULL) != 0) + ABORT("pthread_rwlock_init failed (in child)"); +# endif # else (void)pthread_mutex_destroy(&GC_allocate_ml); /* TODO: Probably some targets might need the default mutex */