From 38ceab15479475d54159de8d2c0d297c56e5f80b Mon Sep 17 00:00:00 2001 From: Zoltan Varga Date: Tue, 7 Feb 2017 14:35:50 -0500 Subject: [PATCH] [runtime] Add a workaround for #50529 by locking around pthread_create()/pthread_join () calls so they can't happen at the same time. (#4332) --- mono/metadata/sgen-mono.c | 8 +++++++- mono/metadata/threads.c | 2 ++ mono/utils/mono-threads.c | 27 +++++++++++++++++++++++++++ mono/utils/mono-threads.h | 3 +++ 4 files changed, 39 insertions(+), 1 deletion(-) diff --git a/mono/metadata/sgen-mono.c b/mono/metadata/sgen-mono.c index f759901a5a0..fc82365a933 100644 --- a/mono/metadata/sgen-mono.c +++ b/mono/metadata/sgen-mono.c @@ -2521,7 +2521,13 @@ mono_gc_deregister_root (char* addr) int mono_gc_pthread_create (pthread_t *new_thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg) { - return pthread_create (new_thread, attr, start_routine, arg); + int res; + + mono_threads_join_lock (); + res = pthread_create (new_thread, attr, start_routine, arg); + mono_threads_join_unlock (); + + return res; } #endif diff --git a/mono/metadata/threads.c b/mono/metadata/threads.c index 28b66c8eb3d..b94a4ff7ff3 100644 --- a/mono/metadata/threads.c +++ b/mono/metadata/threads.c @@ -5085,7 +5085,9 @@ mono_threads_join_threads (void) if (thread != pthread_self ()) { MONO_ENTER_GC_SAFE; /* This shouldn't block */ + mono_threads_join_lock (); mono_native_thread_join (thread); + mono_threads_join_unlock (); MONO_EXIT_GC_SAFE; } } else { diff --git a/mono/utils/mono-threads.c b/mono/utils/mono-threads.c index 401d3b7e3b1..5f719c161e3 100644 --- a/mono/utils/mono-threads.c +++ b/mono/utils/mono-threads.c @@ -75,6 +75,8 @@ static gboolean mono_threads_inited = FALSE; static MonoSemType suspend_semaphore; static size_t pending_suspends; +static mono_mutex_t join_mutex; + #define mono_thread_info_run_state(info) (((MonoThreadInfo*)info)->thread_state & THREAD_STATE_MASK) /*warn at 50 ms*/ @@ -706,6 +708,7 @@ mono_threads_init (MonoThreadInfoCallbacks *callbacks, size_t info_size) mono_os_sem_init (&global_suspend_semaphore, 1); mono_os_sem_init (&suspend_semaphore, 0); + mono_os_mutex_init (&join_mutex); mono_lls_init (&thread_list, NULL); mono_thread_smr_init (); @@ -1231,6 +1234,7 @@ mono_thread_info_yield (void) { return mono_threads_platform_yield (); } + static mono_lazy_init_t sleep_init = MONO_LAZY_INIT_STATUS_NOT_INITIALIZED; static MonoCoopMutex sleep_mutex; static MonoCoopCond sleep_cond; @@ -1689,3 +1693,26 @@ mono_thread_info_wait_multiple_handle (MonoThreadHandle **thread_handles, gsize else g_error ("%s: unknown res value %d", __func__, res); } + +/* + * mono_threads_join_mutex: + * + * This mutex is used to avoid races between pthread_create () and pthread_join () on osx, see + * https://bugzilla.xamarin.com/show_bug.cgi?id=50529 + * The code inside the lock should not block. + */ +void +mono_threads_join_lock (void) +{ +#ifdef TARGET_OSX + mono_os_mutex_lock (&join_mutex); +#endif +} + +void +mono_threads_join_unlock (void) +{ +#ifdef TARGET_OSX + mono_os_mutex_unlock (&join_mutex); +#endif +} diff --git a/mono/utils/mono-threads.h b/mono/utils/mono-threads.h index a5db1c0c4e5..0e77e395663 100644 --- a/mono/utils/mono-threads.h +++ b/mono/utils/mono-threads.h @@ -613,4 +613,7 @@ mono_thread_info_wait_one_handle (MonoThreadHandle *handle, guint32 timeout, gbo MonoThreadInfoWaitRet mono_thread_info_wait_multiple_handle (MonoThreadHandle **thread_handles, gsize nhandles, MonoOSEvent *background_change_event, gboolean waitall, guint32 timeout, gboolean alertable); +void mono_threads_join_lock (void); +void mono_threads_join_unlock (void); + #endif /* __MONO_THREADS_H__ */ -- 2.25.1