From c8ae1605c75899dc9d94d889bfa51ae27acdfd3f Mon Sep 17 00:00:00 2001 From: Yichao Yu Date: Sun, 22 Nov 2015 07:57:53 -0500 Subject: [PATCH] Make sure the tls callback is always initialized before threads starts. --- src/init.c | 4 ++++ src/threading.c | 16 ++++++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/init.c b/src/init.c index 2831eff7d33ff3..1ff7a501e5dae0 100644 --- a/src/init.c +++ b/src/init.c @@ -463,6 +463,10 @@ static void jl_resolve_sysimg_location(JL_IMAGE_SEARCH rel) void _julia_init(JL_IMAGE_SEARCH rel) { +#ifdef JULIA_ENABLE_THREADING + // Make sure we finalize the tls callback before starting any threads. + jl_get_ptls_states_getter(); +#endif libsupport_init(); jl_io_loop = uv_default_loop(); // this loop will internal events (spawning process etc.), // best to call this first, since it also initializes libuv diff --git a/src/threading.c b/src/threading.c index e4b8e62e750bbe..54ad15f0a26605 100644 --- a/src/threading.c +++ b/src/threading.c @@ -47,7 +47,16 @@ static JL_CONST_FUNC jl_tls_states_t *jl_get_ptls_states_fallback(void) # endif return &tls_states; } -static jl_get_ptls_states_func jl_tls_states_cb = jl_get_ptls_states_fallback; +static jl_tls_states_t *jl_get_ptls_states_init(void); +static jl_get_ptls_states_func jl_tls_states_cb = jl_get_ptls_states_init; +static jl_tls_states_t *jl_get_ptls_states_init(void) +{ + // This is clearly not thread safe but should be fine since we + // make sure the tls states callback is finalized before adding + // multiple threads + jl_tls_states_cb = jl_get_ptls_states_fallback; + return jl_get_ptls_states_fallback(); +} DLLEXPORT JL_CONST_FUNC jl_tls_states_t *(jl_get_ptls_states)(void) { return (*jl_tls_states_cb)(); @@ -55,12 +64,15 @@ DLLEXPORT JL_CONST_FUNC jl_tls_states_t *(jl_get_ptls_states)(void) DLLEXPORT void jl_set_ptls_states_getter(jl_get_ptls_states_func f) { // only allow setting this once - if (f && jl_tls_states_cb == jl_get_ptls_states_fallback) { + if (f && f != jl_get_ptls_states_init && + jl_tls_states_cb == jl_get_ptls_states_init) { jl_tls_states_cb = f; } } jl_get_ptls_states_func jl_get_ptls_states_getter(void) { + if (jl_tls_states_cb == jl_get_ptls_states_init) + jl_get_ptls_states_init(); // for codegen return jl_tls_states_cb; }