diff options
author | Karl Williamson <khw@cpan.org> | 2018-02-13 13:12:50 -0700 |
---|---|---|
committer | Karl Williamson <khw@cpan.org> | 2018-02-18 15:44:23 -0700 |
commit | 49d7d366441813aa7301b1a437e302372f04f31a (patch) | |
tree | 619c3271adeeab23fe9ea25c9517ebf9807cc1fe /vutil.c | |
parent | 398eeea9cd1c8a9b95329a3eca8be6a2a5903ac5 (diff) | |
download | perl-49d7d366441813aa7301b1a437e302372f04f31a.tar.gz |
Latch LC_NUMERIC during critical sections
It is possible for operations on threaded perls which don't 'use locale'
to still change the locale. This happens when calling
POSIX::localeconv() and I18N::Langinfo(), and in earlier perls, it can
happen for other operations when perl has been initialized with the
environment causing the various locale categories to not have a uniform
locale.
This commit causes the areas where the locale for this category should
predictably be in one or the other state to be a critical section where
another thread can't interrupt and change it. This is a separate
mutex, so that only these particular operations will be held up.
Diffstat (limited to 'vutil.c')
-rw-r--r-- | vutil.c | 6 |
1 files changed, 6 insertions, 0 deletions
@@ -628,6 +628,8 @@ VER_NV: /* if it isn't C, set it to C. */ const char * locale_name_on_entry; + LC_NUMERIC_LOCK(0); /* Start critical section */ + locale_name_on_entry = setlocale(LC_NUMERIC, NULL); if ( strNE(locale_name_on_entry, "C") && strNE(locale_name_on_entry, "POSIX")) @@ -638,6 +640,7 @@ VER_NV: change the locale */ locale_name_on_entry = NULL; } + /* Prevent recursed calls from trying to change back */ LOCK_LC_NUMERIC_STANDARD(); @@ -660,6 +663,9 @@ VER_NV: if (locale_name_on_entry) { setlocale(LC_NUMERIC, locale_name_on_entry); } + + LC_NUMERIC_UNLOCK; /* End critical section */ + } #endif /* USE_LOCALE_NUMERIC */ |