summaryrefslogtreecommitdiff
path: root/sv.c
diff options
context:
space:
mode:
authorKarl Williamson <khw@cpan.org>2022-09-29 09:38:36 -0600
committerKarl Williamson <khw@cpan.org>2022-10-18 06:22:16 -0600
commit1094750e0904f86121732c4af342fbdaccf70df3 (patch)
tree498928a6fb03864ddd8865b27bd1ba602a49f5ad /sv.c
parent7af2d2037375d58e700f9e1b217efb2c4db66133 (diff)
downloadperl-1094750e0904f86121732c4af342fbdaccf70df3.tar.gz
Some locale operations need to be done in proper thread
This is a step in solving #20155 The POSIX 2008 locale API introduces per-thread locales. But the previous global locale system is retained, probably for backward compatibility. The POSIX 2008 interface causes memory to be malloc'd that needs to be freed. In order to do this, the caller must first stop using that memory, by switching to another locale. perl accomplishes this during termination by switching to the global locale, which is always available and doesn't need to be freed. Perl has long assumed that all that was needed to switch threads was to change out tTHX. That's because that structure was intended to hold all the information for a given thread. But it turns out that this doesn't work when some library independently holds information about the thread's state. And there are now some libraries that do that. What was happening in this case was that perl thought that it was sufficient to switch tTHX to change to a different thread in order to do the freeing of memory, and then used the POSIX 2008 function to change to the global locale so that the memory could be safely freed. But the POSIX 2008 function doesn't care about tTHX, and actually was typically operating on a different thread, and so changed that thread to the global locale instead of the intended thread. Often that was the top-level thread, thread 0. That caused whatever thread it was to no longer be in the expected locale, and to no longer be thread-safe with regards to localess, This commit causes locale_term(), which has always been called from the actual terminating thread that POSIX 2008 knows about, to change to the global thread and free the memory. It also creates a new per-interpreter variable that effectively maps the tTHX thread to the associated POSIX 2008 memory. During perl_destruct(), it frees the memory this variable points to, instead of blindly assuming the memory to free is the current tTHX thread's. This fixes the symptoms associtated with #20155, but doesn't solve the whole problem. In general, a library that has independent thread status needs to be updated to the new thread when Perl changes threads using tTHX. Future commits will do this.
Diffstat (limited to 'sv.c')
-rw-r--r--sv.c1
1 files changed, 1 insertions, 0 deletions
diff --git a/sv.c b/sv.c
index bc5f95143b..99b71c65ab 100644
--- a/sv.c
+++ b/sv.c
@@ -15939,6 +15939,7 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags,
#endif /* !USE_LOCALE_NUMERIC */
#if defined(USE_POSIX_2008_LOCALE)
PL_scratch_locale_obj = NULL;
+ PL_cur_locale_obj = PL_C_locale_obj;
#endif
#ifdef HAS_MBRLEN