Skip to content

Commit

Permalink
locale.c: Clean up handling of a glibc bug
Browse files Browse the repository at this point in the history
This commit moves all mention of this bug to just the code that requires
it, and inlines a macro, making it easier to comprehend
  • Loading branch information
khwilliamson committed Apr 29, 2021
1 parent 6d43101 commit 2b78f4f
Showing 1 changed file with 29 additions and 16 deletions.
45 changes: 29 additions & 16 deletions locale.c
Expand Up @@ -482,8 +482,6 @@ S_category_name(const int category)
# define querylocale_c(cat) querylocale_r(cat)
# define querylocale_i(i) querylocale_c(categories[i])

# define FIX_GLIBC_LC_MESSAGES_BUG(i)

#else /* Below uses POSIX 2008 */

/* Here, there is a completely different API to get thread-safe locales. We
Expand Down Expand Up @@ -533,18 +531,9 @@ S_category_name(const int category)
querylocale(category_masks[index], locale_obj))
# endif
# endif
# if ! defined(__GLIBC__) || ! defined(USE_LOCALE_MESSAGES)
# define FIX_GLIBC_LC_MESSAGES_BUG(i)
# else /* Invalidate glibc cache of loaded translations, see [perl #134264] */

# if defined(__GLIBC__) && defined(USE_LOCALE_MESSAGES)
# define HAS_GLIBC_LC_MESSAGES_BUG
# include <libintl.h>
# define FIX_GLIBC_LC_MESSAGES_BUG(i) \
STMT_START { \
if ((i) == LC_MESSAGES_INDEX_) { \
textdomain(textdomain(NULL)); \
} \
} STMT_END

# endif

/* A fourth array, parallel to the ones above to map from category to its
Expand Down Expand Up @@ -804,6 +793,7 @@ S_emulate_setlocale_i(pTHX_ const unsigned int index, const char * new_locale)
int mask;
locale_t old_obj;
locale_t new_obj;
const char * old_messages_locale = NULL;

PERL_ARGS_ASSERT_EMULATE_SETLOCALE_I;
assert(index <= NOMINAL_LC_ALL_INDEX);
Expand Down Expand Up @@ -939,6 +929,20 @@ S_emulate_setlocale_i(pTHX_ const unsigned int index, const char * new_locale)
* This would have come for free if this system had had querylocale() */

# endif /* end of ! querylocale */
# ifdef HAS_GLIBC_LC_MESSAGES_BUG

/* For this bug, if the LC_MESSAGES locale changes, we have to do an
* expensive workaround. Save the current value so we can later determine
* if it changed. */
if ( (index == LC_MESSAGES_INDEX_ || index == LC_ALL_INDEX_)
&& LIKELY(PL_phase != PERL_PHASE_CONSTRUCT))
{
old_messages_locale = savepv(querylocale_c(LC_MESSAGES));
}

# else
PERL_UNUSED_VAR(old_messages_locale);
# endif

assert(PL_C_locale_obj);

Expand Down Expand Up @@ -1076,8 +1080,6 @@ S_emulate_setlocale_i(pTHX_ const unsigned int index, const char * new_locale)
Safefree(PL_curlocales[i]);
PL_curlocales[i] = savepv(new_locale);
}

FIX_GLIBC_LC_MESSAGES_BUG(LC_MESSAGES_INDEX_);
}
else {

Expand All @@ -1093,8 +1095,19 @@ S_emulate_setlocale_i(pTHX_ const unsigned int index, const char * new_locale)
PL_curlocales[LC_ALL_INDEX_] =
savepv(calculate_LC_ALL(PL_curlocales));
}
}

# endif
# ifdef HAS_GLIBC_LC_MESSAGES_BUG

/* Invalidate the glibc cache of loaded translations if the locale has changed,
* see [perl #134264] */
if (old_messages_locale) {
if (strNE(old_messages_locale, my_querylocale_c(LC_MESSAGES))) {
textdomain(textdomain(NULL));
}

FIX_GLIBC_LC_MESSAGES_BUG(index);
Safefree(old_messages_locale);
}

# endif
Expand Down

0 comments on commit 2b78f4f

Please sign in to comment.