summaryrefslogtreecommitdiff
path: root/pthread_support.c
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2012-02-26 16:36:11 +0100
committerIvan Maidanski <ivmai@mail.ru>2012-02-26 18:18:44 +0100
commit6f7c0b722b59669d5c49b7af6cbbef86044558ec (patch)
tree6cb9ae33d359008c4a92169a0ca4459e9d29adc9 /pthread_support.c
parent1a50eb1637ab9da9e7d8a206d3c876d9aa724526 (diff)
Fix GC_remove_all_threads_but_me for fork-unfriendly TLS implementations
* pthread_support.c (GC_remove_all_threads_but_me): Refine comment for stop_info.mach_thread update. * pthread_support.c (GC_remove_all_threads_but_me): Call GC_setspecific (if THREAD_LOCAL_ALLOC) to re-assign thread-local pointer to 'tlfs' (identified by GC_thread_key) of the current thread (except for USE_CUSTOM_SPECIFIC).
Diffstat (limited to 'pthread_support.c')
-rw-r--r--pthread_support.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/pthread_support.c b/pthread_support.c
index 775a2fc..35c1771 100644
--- a/pthread_support.c
+++ b/pthread_support.c
@@ -632,9 +632,19 @@ STATIC void GC_remove_all_threads_but_me(void)
me = p;
p -> next = 0;
# ifdef GC_DARWIN_THREADS
- /* Update thread Id after fork. */
+ /* Update thread Id after fork (it is ok to call */
+ /* GC_destroy_thread_local and GC_free_internal */
+ /* before update). */
me -> stop_info.mach_thread = mach_thread_self();
# endif
+# if defined(THREAD_LOCAL_ALLOC) && !defined(USE_CUSTOM_SPECIFIC)
+ /* Some TLS implementations might be not fork-friendly, so */
+ /* we re-assign thread-local pointer to 'tlfs' for safety */
+ /* instead of the assertion check (again, it is ok to call */
+ /* GC_destroy_thread_local and GC_free_internal before). */
+ if (GC_setspecific(GC_thread_key, &me->tlfs) != 0)
+ ABORT("GC_setspecific failed (in child)");
+# endif
} else {
# ifdef THREAD_LOCAL_ALLOC
if (!(p -> flags & FINISHED)) {