From 0f31431b38936983c803c10b241f55299818baad Mon Sep 17 00:00:00 2001 From: David Chisnall Date: Thu, 24 Nov 2011 17:02:08 +0000 Subject: Add fake TLS support so that we work for single-threaded programs when not linked to pthread. --- src/exception.cc | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/exception.cc b/src/exception.cc index abf6a10..0896354 100644 --- a/src/exception.cc +++ b/src/exception.cc @@ -288,12 +288,25 @@ static void thread_cleanup(void* thread_info) */ static pthread_once_t once_control = PTHREAD_ONCE_INIT; +/** + * We may not be linked against a full pthread implementation. If we're not, + * then we need to fake the thread-local storage by storing 'thread-local' + * things in a global. + */ +static bool fakeTLS; +/** + * Thread-local storage for a single-threaded program. + */ +static __cxa_thread_info singleThreadInfo; /** * Initialise eh_key. */ static void init_key(void) { pthread_key_create(&eh_key, thread_cleanup); + pthread_setspecific(eh_key, (void*)0x42); + fakeTLS = (pthread_getspecific(eh_key) != (void*)0x42); + pthread_setspecific(eh_key, 0); } /** @@ -301,7 +314,11 @@ static void init_key(void) */ static __cxa_thread_info *thread_info() { - pthread_once(&once_control, init_key); + if (pthread_once(&once_control, init_key)) + { + fakeTLS = true; + } + if (fakeTLS) { return &singleThreadInfo; } __cxa_thread_info *info = (__cxa_thread_info*)pthread_getspecific(eh_key); if (0 == info) { @@ -316,6 +333,7 @@ static __cxa_thread_info *thread_info() */ static __cxa_thread_info *thread_info_fast() { + if (fakeTLS) { return &singleThreadInfo; } return (__cxa_thread_info*)pthread_getspecific(eh_key); } /** -- cgit v1.2.3