Skip to content

Commit

Permalink
locale.c: Workaround for attributes.pm breakage
Browse files Browse the repository at this point in the history
See Perl#20155

The root cause of that problem is that under POSIX 2008, when a thread
terminates, it causes thread 0 (the controller) to change to the global
locale.  Commit a7ff7ac caused perl to pay attention to the environment
variables in effect at startup for setting the global locale when using
the POSIX 2008 locale API.  (Previously only the initial per-thread
locale was affected.)

This causes problems when the initial setting was for a locale that uses
a comma as the radix character, but the thread 0 is set to a locale that
is expecting a dot as a radix character.  Whenever another thread
terminates, thread 0 was silently changed to using the global locake,
and hence a comma.  This caused parse errors.

The real solution is to fix thread 0 to remain in its chosen locale.
But that fix is not ready in time for 5.37.4, and it is deemed important
to get something working for this monthly development release.

This commit changes the initial global LC_NUMERIC locale to always be C,
hence uses a dot radix.  The vast majority of code is expecting a dot.
This is not the ultimate fix, but it works around the immediate problem
at hand.

The test case is courtesy @bram-perl
  • Loading branch information
khwilliamson authored and scottchiefbaker committed Nov 3, 2022
1 parent adf6751 commit bf09a9e
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 0 deletions.
9 changes: 9 additions & 0 deletions locale.c
Original file line number Diff line number Diff line change
Expand Up @@ -5011,6 +5011,15 @@ Perl_init_i18nl10n(pTHX_ int printwarn)
/* Done with finding the locales; update the auxiliary records */
new_LC_ALL(NULL);

# if defined(USE_POSIX_2008_LOCALE) && defined(USE_LOCALE_NUMERIC)

/* This is a temporary workaround for #20155, to avoid issues where the
* global locale wants a radix different from the per-thread one. This
* restores behavior for LC_NUMERIC to what it was before a7ff7ac. */
posix_setlocale(LC_NUMERIC, "C");

# endif

for (i = 0; i < NOMINAL_LC_ALL_INDEX; i++) {
Safefree(curlocales[i]);
}
Expand Down
25 changes: 25 additions & 0 deletions t/run/locale.t
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,31 @@ EOF
EOF
"1,5\n2,5", { stderr => 'devnull' }, "Can do math when radix is a comma"); # [perl 115800]

SKIP: {
skip "Perl not compiled with 'useithreads'", 1 if ! $Config{'useithreads'};

local $ENV{LC_ALL} = undef;
local $ENV{LC_NUMERIC} = $comma;
fresh_perl_is(<<"EOF",
use threads;
my \$x = eval "1.25";
print "\$x", "\n"; # number is ok before thread
my \$str_x = "\$x";
my \$thr = threads->create(sub {});
\$thr->join();
print "\$x\n"; # number stringifies the same after thread
my \$y = eval "1.25";
print "\$y\n"; # number is ok after threads
print "\$y" eq "\$str_x" || 0; # new number stringifies the same as old number
EOF
"1.25\n1.25\n1.25\n1", { }, "Thread join doesn't disrupt calling thread"
); # [GH 20155]
}

SKIP: {
unless ($have_strtod) {
skip("no strtod()", 1);
Expand Down

0 comments on commit bf09a9e

Please sign in to comment.