diff options
author | Karl Williamson <khw@cpan.org> | 2022-09-29 12:51:21 -0600 |
---|---|---|
committer | Karl Williamson <khw@cpan.org> | 2022-10-18 06:22:16 -0600 |
commit | 644641ff58ccf88bd860ef5517a40d1fb27bf022 (patch) | |
tree | ef894cfcba475a235aa64d806d1e1052e9695d9b /perl.h | |
parent | 1094750e0904f86121732c4af342fbdaccf70df3 (diff) | |
download | perl-644641ff58ccf88bd860ef5517a40d1fb27bf022.tar.gz |
Switch libc per-interpreter data when tTHX changes
As noted in the previous commit, some library functions now keep
per-thread state. So far the only ones we care about are libc
locale-changing ones.
When perl changes threads by swapping out tTHX, those library functions
need to be informed about the new value so that they remain in sync with
what perl thinks the locale should be.
This commit creates a function to do this, and changes the
thread-changing macros to also call this as part of the change.
For POSIX 2008, the function just calls uselocale() using the
per-interpreter object introduced previously.
For Windows, this commit adds a per-interpreter string of the current
LC_ALL, and the function calls setlocale on that. We keep the same
string for POSIX 2008 implementations that lack querylocale(), so this
commit just enables that variable on Windows as well. The code is
already in place to free the memory the string occupies when done.
The commit also creates a mechanism to skip this during thread
destruction. A thread in its death throes doesn't need to have accurate
locale information, and the information needed to map from thread to
what libc needs to know gets destroyed as part of those throes, while
relics of the thread remain. I couldn't find a way to accurately know
if we are dealing with a relic or not, so the solution I adopted was to
just not switch during destruction.
This commit completes fixing #20155.
Diffstat (limited to 'perl.h')
-rw-r--r-- | perl.h | 41 |
1 files changed, 39 insertions, 2 deletions
@@ -1272,6 +1272,11 @@ violations are fatal. # if defined(WIN32) && defined(USE_THREAD_SAFE_LOCALE) + /* We need to be able to map the current value of what the tTHX context + * thinks LC_ALL is so as to inform the Windows libc when switching + * contexts. */ +# define USE_PL_CUR_LC_ALL + /* Microsoft documentation reads in the change log for VS 2015: "The * localeconv function declared in locale.h now works correctly when * per-thread locale is enabled. In previous versions of the library, this @@ -1281,6 +1286,15 @@ violations are fatal. # define TS_W32_BROKEN_LOCALECONV # endif # endif + + /* POSIX 2008 and Windows with thread-safe locales keep locale information + * in libc data. Therefore we must inform their libc's when the context + * switches */ +# if defined(MULTIPLICITY) && ( defined(USE_POSIX_2008_LOCALE) \ + || ( defined(WIN32) \ + && defined(USE_THREAD_SAFE_LOCALE))) +# define USE_PERL_SWITCH_LOCALE_CONTEXT +# endif #endif /* end of makedef.pl logic duplication @@ -4046,7 +4060,10 @@ out there, Solaris being the most prominent. /* the traditional thread-unsafe notion of "current interpreter". */ #ifndef PERL_SET_INTERP -# define PERL_SET_INTERP(i) (PL_curinterp = (PerlInterpreter*)(i)) +# define PERL_SET_INTERP(i) \ + STMT_START { PL_curinterp = (PerlInterpreter*)(i); \ + PERL_SET_NON_tTHX_CONTEXT(i); \ + } STMT_END #endif #ifndef PERL_GET_INTERP @@ -6273,6 +6290,24 @@ EXTCONST U8 PL_deBruijn_bitpos_tab64[]; # define PERL_SET_CONTEXT(i) PERL_SET_INTERP(i) #endif +#ifdef USE_PERL_SWITCH_LOCALE_CONTEXT +# define PERL_SET_LOCALE_CONTEXT(i) \ + STMT_START { \ + if (UNLIKELY(PL_veto_switch_non_tTHX_context)) \ + Perl_switch_locale_context(); \ + } STMT_END +#else +# define PERL_SET_LOCALE_CONTEXT(i) NOOP +#endif + +/* In some Configurations there may be per-thread information that is carried + * in a library instead of perl's tTHX structure. This macro is to be used to + * handle those when tTHX is changed. Only locale handling is currently known + * to be affected. */ +#define PERL_SET_NON_tTHX_CONTEXT(i) \ + STMT_START { PERL_SET_LOCALE_CONTEXT(i); } STMT_END + + #ifndef PERL_GET_CONTEXT # define PERL_GET_CONTEXT PERL_GET_INTERP #endif @@ -7883,7 +7918,9 @@ C<strtoul>. * "DynaLoader::_guts" XS_VERSION * XXX in the current implementation, this string is ignored. * 2. Declare a typedef named my_cxt_t that is a structure that contains - * all the data that needs to be interpreter-local. + * all the data that needs to be interpreter-local that perl controls. This + * doesn't include things that libc controls, such as the uselocale object + * in Configurations that use it. * 3. Use the START_MY_CXT macro after the declaration of my_cxt_t. * 4. Use the MY_CXT_INIT macro such that it is called exactly once * (typically put in the BOOT: section). |