diff options
author | Karl Williamson <khw@cpan.org> | 2018-01-17 13:32:32 -0700 |
---|---|---|
committer | Karl Williamson <khw@cpan.org> | 2018-01-31 06:57:50 -0700 |
commit | 7d5966ae3c3b8f0e43fa09554a46cb8de9c98f5f (patch) | |
tree | c49c3bceab87d754e6e1d57c1acef50068ee4cbc /ext/POSIX/POSIX.xs | |
parent | 6e4200280cd1c3843eea21c73aab78a8c7063027 (diff) | |
download | perl-7d5966ae3c3b8f0e43fa09554a46cb8de9c98f5f.tar.gz |
POSIX::localconv(): Prefer localeconv_l()
This is a thread-safe version of localeconv(), so use it under threads.
Diffstat (limited to 'ext/POSIX/POSIX.xs')
-rw-r--r-- | ext/POSIX/POSIX.xs | 29 |
1 files changed, 26 insertions, 3 deletions
diff --git a/ext/POSIX/POSIX.xs b/ext/POSIX/POSIX.xs index 0ab9470832..1dbcd076e4 100644 --- a/ext/POSIX/POSIX.xs +++ b/ext/POSIX/POSIX.xs @@ -2124,7 +2124,12 @@ localeconv() localeconv(); /* A stub to call not_here(). */ #else struct lconv *lcbuf; - +# if defined(USE_ITHREADS) \ + && defined(HAS_POSIX_2008_LOCALE) \ + && defined(HAS_LOCALECONV_L) /* Prefer this thread-safe version */ + bool do_free = FALSE; + locale_t cur = uselocale((locale_t) 0); +# endif DECLARATION_FOR_LC_NUMERIC_MANIPULATION; /* localeconv() deals with both LC_NUMERIC and LC_MONETARY, but @@ -2144,11 +2149,22 @@ localeconv() RETVAL = newHV(); sv_2mortal((SV*)RETVAL); +# if defined(USE_ITHREADS) \ + && defined(HAS_POSIX_2008_LOCALE) \ + && defined(HAS_LOCALECONV_L) + + if (cur == LC_GLOBAL_LOCALE) { + cur = duplocale(LC_GLOBAL_LOCALE); + do_free = TRUE; + } + lcbuf = localeconv_l(cur); +# else LOCALE_LOCK; /* Prevent interference with other threads using localeconv() */ - lcbuf = localeconv(); + lcbuf = localeconv(); +# endif if (lcbuf) { const struct lconv_offset *strings = lconv_strings; const struct lconv_offset *integers = lconv_integers; @@ -2199,8 +2215,15 @@ localeconv() integers++; } } - +# if defined(USE_ITHREADS) \ + && defined(HAS_POSIX_2008_LOCALE) \ + && defined(HAS_LOCALECONV_L) + if (do_free) { + freelocale(cur); + } +# else LOCALE_UNLOCK; +# endif RESTORE_LC_NUMERIC(); #endif /* HAS_LOCALECONV */ OUTPUT: |