Changeset View
Changeset View
Standalone View
Standalone View
lib/libc/locale/xlocale.c
Show First 20 Lines • Show All 49 Lines • ▼ Show 20 Lines | |||||
extern struct xlocale_component __xlocale_global_messages; | extern struct xlocale_component __xlocale_global_messages; | ||||
/* | /* | ||||
* And another version for the statically-allocated C locale. We only have | * And another version for the statically-allocated C locale. We only have | ||||
* components for the parts that are expected to be sensible. | * components for the parts that are expected to be sensible. | ||||
*/ | */ | ||||
extern struct xlocale_component __xlocale_C_collate; | extern struct xlocale_component __xlocale_C_collate; | ||||
extern struct xlocale_component __xlocale_C_ctype; | extern struct xlocale_component __xlocale_C_ctype; | ||||
#ifndef __NO_TLS | |||||
/* | /* | ||||
* The locale for this thread. | * The locale for this thread. | ||||
*/ | */ | ||||
_Thread_local locale_t __thread_locale; | _Thread_local locale_t __thread_locale; | ||||
#endif | |||||
/* | /* | ||||
* Flag indicating that one or more per-thread locales exist. | * Flag indicating that one or more per-thread locales exist. | ||||
*/ | */ | ||||
int __has_thread_locale; | int __has_thread_locale; | ||||
/* | /* | ||||
* Private functions in setlocale.c. | * Private functions in setlocale.c. | ||||
*/ | */ | ||||
const char * | const char * | ||||
▲ Show 20 Lines • Show All 66 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
_once(&once_control, init_key); | _once(&once_control, init_key); | ||||
return (fake_tls ? thread_local_locale : | return (fake_tls ? thread_local_locale : | ||||
pthread_getspecific(locale_info_key)); | pthread_getspecific(locale_info_key)); | ||||
} | } | ||||
#ifdef __NO_TLS | |||||
locale_t | |||||
__get_locale(void) | |||||
{ | |||||
locale_t l = get_thread_locale(); | |||||
return (l ? l : &__xlocale_global_locale); | |||||
} | |||||
#endif | |||||
static void | static void | ||||
set_thread_locale(locale_t loc) | set_thread_locale(locale_t loc) | ||||
{ | { | ||||
locale_t l = (loc == LC_GLOBAL_LOCALE) ? 0 : loc; | locale_t l = (loc == LC_GLOBAL_LOCALE) ? 0 : loc; | ||||
_once(&once_control, init_key); | _once(&once_control, init_key); | ||||
if (NULL != l) { | if (NULL != l) { | ||||
xlocale_retain((struct xlocale_refcounted*)l); | xlocale_retain((struct xlocale_refcounted*)l); | ||||
} | } | ||||
locale_t old = get_thread_locale(); | locale_t old = get_thread_locale(); | ||||
if ((NULL != old) && (l != old)) { | if ((NULL != old) && (l != old)) { | ||||
xlocale_release((struct xlocale_refcounted*)old); | xlocale_release((struct xlocale_refcounted*)old); | ||||
} | } | ||||
if (fake_tls) { | if (fake_tls) { | ||||
thread_local_locale = l; | thread_local_locale = l; | ||||
} else { | } else { | ||||
pthread_setspecific(locale_info_key, l); | pthread_setspecific(locale_info_key, l); | ||||
} | } | ||||
#ifndef __NO_TLS | |||||
__thread_locale = l; | __thread_locale = l; | ||||
__set_thread_rune_locale(loc); | __set_thread_rune_locale(loc); | ||||
#endif | |||||
} | } | ||||
/** | /** | ||||
* Clean up a locale, once its reference count reaches zero. This function is | * Clean up a locale, once its reference count reaches zero. This function is | ||||
* called by xlocale_release(), it should not be called directly. | * called by xlocale_release(), it should not be called directly. | ||||
*/ | */ | ||||
static void | static void | ||||
destruct_locale(void *l) | destruct_locale(void *l) | ||||
▲ Show 20 Lines • Show All 196 Lines • Show Last 20 Lines |