[glib/icu/ucdn] Make the funcs object allocated on demand

This commit is contained in:
Behdad Esfahbod 2017-10-27 15:26:45 -06:00
parent af3f72f9eb
commit 8864864b62
3 changed files with 95 additions and 29 deletions

View File

@ -364,22 +364,44 @@ hb_glib_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs HB_UNUSED,
return utf8_decomposed_len; return utf8_decomposed_len;
} }
static hb_unicode_funcs_t *static_glib_funcs = nullptr;
#ifdef HB_USE_ATEXIT
static
void free_static_glib_funcs (void)
{
hb_unicode_funcs_destroy (static_glib_funcs);
}
#endif
hb_unicode_funcs_t * hb_unicode_funcs_t *
hb_glib_get_unicode_funcs (void) hb_glib_get_unicode_funcs (void)
{ {
static const hb_unicode_funcs_t _hb_glib_unicode_funcs = { retry:
HB_OBJECT_HEADER_STATIC, hb_unicode_funcs_t *funcs = (hb_unicode_funcs_t *) hb_atomic_ptr_get (&static_glib_funcs);
nullptr, /* parent */ if (unlikely (!funcs))
true, /* immutable */ {
{ funcs = hb_unicode_funcs_create (nullptr);
#define HB_UNICODE_FUNC_IMPLEMENT(name) hb_glib_unicode_##name,
#define HB_UNICODE_FUNC_IMPLEMENT(name) \
hb_unicode_funcs_set_##name##_func (funcs, hb_glib_unicode_##name, nullptr, nullptr);
HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
#undef HB_UNICODE_FUNC_IMPLEMENT #undef HB_UNICODE_FUNC_IMPLEMENT
hb_unicode_funcs_make_immutable (funcs);
if (!hb_atomic_ptr_cmpexch (&static_glib_funcs, nullptr, funcs)) {
hb_unicode_funcs_destroy (funcs);
goto retry;
} }
#ifdef HB_USE_ATEXIT
atexit (free_static_glib_funcs); /* First person registers atexit() callback. */
#endif
}; };
return const_cast<hb_unicode_funcs_t *> (&_hb_glib_unicode_funcs); return funcs;
} }
#if GLIB_CHECK_VERSION(2,31,10) #if GLIB_CHECK_VERSION(2,31,10)

View File

@ -345,27 +345,50 @@ hb_icu_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs HB_UNUSED,
} }
static hb_unicode_funcs_t *static_icu_funcs = nullptr;
#ifdef HB_USE_ATEXIT
static
void free_static_icu_funcs (void)
{
hb_unicode_funcs_destroy (static_icu_funcs);
}
#endif
hb_unicode_funcs_t * hb_unicode_funcs_t *
hb_icu_get_unicode_funcs (void) hb_icu_get_unicode_funcs (void)
{ {
static const hb_unicode_funcs_t _hb_icu_unicode_funcs = { retry:
HB_OBJECT_HEADER_STATIC, hb_unicode_funcs_t *funcs = (hb_unicode_funcs_t *) hb_atomic_ptr_get (&static_icu_funcs);
nullptr, /* parent */ if (unlikely (!funcs))
true, /* immutable */ {
{ #if U_ICU_VERSION_MAJOR_NUM >= 49
#define HB_UNICODE_FUNC_IMPLEMENT(name) hb_icu_unicode_##name, if (!hb_atomic_ptr_get (&normalizer)) {
UErrorCode icu_err = U_ZERO_ERROR;
/* We ignore failure in getNFCInstace(). */
(void) hb_atomic_ptr_cmpexch (&normalizer, nullptr, unorm2_getNFCInstance (&icu_err));
}
#endif
funcs = hb_unicode_funcs_create (nullptr);
#define HB_UNICODE_FUNC_IMPLEMENT(name) \
hb_unicode_funcs_set_##name##_func (funcs, hb_icu_unicode_##name, nullptr, nullptr);
HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
#undef HB_UNICODE_FUNC_IMPLEMENT #undef HB_UNICODE_FUNC_IMPLEMENT
hb_unicode_funcs_make_immutable (funcs);
if (!hb_atomic_ptr_cmpexch (&static_icu_funcs, nullptr, funcs)) {
hb_unicode_funcs_destroy (funcs);
goto retry;
} }
#ifdef HB_USE_ATEXIT
atexit (free_static_icu_funcs); /* First person registers atexit() callback. */
#endif
}; };
#if U_ICU_VERSION_MAJOR_NUM >= 49 return funcs;
if (!hb_atomic_ptr_get (&normalizer)) {
UErrorCode icu_err = U_ZERO_ERROR;
/* We ignore failure in getNFCInstace(). */
(void) hb_atomic_ptr_cmpexch (&normalizer, nullptr, unorm2_getNFCInstance (&icu_err));
}
#endif
return const_cast<hb_unicode_funcs_t *> (&_hb_icu_unicode_funcs);
} }

View File

@ -231,22 +231,43 @@ hb_ucdn_decompose_compatibility(hb_unicode_funcs_t *ufuncs HB_UNUSED,
return ucdn_compat_decompose(u, decomposed); return ucdn_compat_decompose(u, decomposed);
} }
static hb_unicode_funcs_t *static_ucdn_funcs = nullptr;
#ifdef HB_USE_ATEXIT
static
void free_static_ucdn_funcs (void)
{
hb_unicode_funcs_destroy (static_ucdn_funcs);
}
#endif
extern "C" HB_INTERNAL extern "C" HB_INTERNAL
hb_unicode_funcs_t * hb_unicode_funcs_t *
hb_ucdn_get_unicode_funcs (void) hb_ucdn_get_unicode_funcs (void)
{ {
static const hb_unicode_funcs_t _hb_ucdn_unicode_funcs = { retry:
HB_OBJECT_HEADER_STATIC, hb_unicode_funcs_t *funcs = (hb_unicode_funcs_t *) hb_atomic_ptr_get (&static_ucdn_funcs);
nullptr, /* parent */ if (unlikely (!funcs))
true, /* immutable */ {
{ funcs = hb_unicode_funcs_create (nullptr);
#define HB_UNICODE_FUNC_IMPLEMENT(name) hb_ucdn_##name,
#define HB_UNICODE_FUNC_IMPLEMENT(name) \
hb_unicode_funcs_set_##name##_func (funcs, hb_ucdn_##name, nullptr, nullptr);
HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
#undef HB_UNICODE_FUNC_IMPLEMENT #undef HB_UNICODE_FUNC_IMPLEMENT
hb_unicode_funcs_make_immutable (funcs);
if (!hb_atomic_ptr_cmpexch (&static_ucdn_funcs, nullptr, funcs)) {
hb_unicode_funcs_destroy (funcs);
goto retry;
} }
#ifdef HB_USE_ATEXIT
atexit (free_static_ucdn_funcs); /* First person registers atexit() callback. */
#endif
}; };
return const_cast<hb_unicode_funcs_t *> (&_hb_ucdn_unicode_funcs); return funcs;
} }