summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--thread.h18
-rw-r--r--util.c9
2 files changed, 17 insertions, 10 deletions
diff --git a/thread.h b/thread.h
index cfa3287b5c..dd98a43b6d 100644
--- a/thread.h
+++ b/thread.h
@@ -387,7 +387,9 @@ extern PERL_THREAD_LOCAL void *PL_current_context;
# define PERL_GET_CONTEXT PL_current_context
-/* Set our thread-specific value anyway, in case code is reading it directly. */
+/* We must also call pthread_setspecific() always, as C++ code has to read it
+ * with pthreads (the #else side just below) */
+
# define PERL_SET_CONTEXT(t) \
STMT_START { \
int _eC_; \
@@ -403,14 +405,14 @@ extern PERL_THREAD_LOCAL void *PL_current_context;
# define PERL_GET_CONTEXT PTHREAD_GETSPECIFIC(PL_thr_key)
# endif
+/* For C++ extensions built on a system where the C compiler provides thread
+ * local storage that call PERL_SET_CONTEXT() also need to set
+ * PL_current_context, so need to call into C code to do this.
+ * To avoid exploding code complexity, do this also on C platforms that don't
+ * support thread local storage. PERL_SET_CONTEXT is not called that often. */
+
# ifndef PERL_SET_CONTEXT
-# define PERL_SET_CONTEXT(t) \
- STMT_START { \
- int _eC_; \
- if ((_eC_ = pthread_setspecific(PL_thr_key, (void *)(t)))) \
- Perl_croak_nocontext("panic: pthread_setspecific (%d) [%s:%d]", \
- _eC_, __FILE__, __LINE__); \
- } STMT_END
+# define PERL_SET_CONTEXT(t) Perl_set_context((void*)t)
# endif /* PERL_SET_CONTEXT */
#endif /* PERL_THREAD_LOCAL */
diff --git a/util.c b/util.c
index 4cfe6416b9..b1da8e35c8 100644
--- a/util.c
+++ b/util.c
@@ -3762,13 +3762,18 @@ Perl_get_context(void)
void
Perl_set_context(void *t)
{
-#if defined(USE_ITHREADS)
-#endif
PERL_ARGS_ASSERT_SET_CONTEXT;
#if defined(USE_ITHREADS)
+# ifdef PERL_USE_THREAD_LOCAL
+ PL_current_context = t;
+# endif
# ifdef I_MACH_CTHREADS
cthread_set_data(cthread_self(), t);
# else
+ /* We set thread-specific value always, as C++ code has to read it with
+ * pthreads, beacuse the declaration syntax for thread local storage for C11
+ * is incompatible with C++, meaning that we can't expose the thread local
+ * variable to C++ code. */
{
const int error = pthread_setspecific(PL_thr_key, t);
if (error)