[ucdn/glib/icu] Port unicode_funcs statics to lazy-loader

This commit is contained in:
Behdad Esfahbod 2018-08-12 13:39:01 -07:00
parent 1b6b481262
commit cb3fc3685c
4 changed files with 97 additions and 109 deletions

View File

@ -31,6 +31,7 @@
#include "hb-glib.h"
#include "hb-unicode-private.hh"
#include "hb-machinery-private.hh"
#if !GLIB_CHECK_VERSION(2,29,14)
@ -364,30 +365,15 @@ hb_glib_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs HB_UNUSED,
return utf8_decomposed_len;
}
static hb_atomic_ptr_t<hb_unicode_funcs_t> static_glib_funcs;
#ifdef HB_USE_ATEXIT
static
void free_static_glib_funcs (void)
static void free_static_glib_funcs (void);
static struct hb_glib_unicode_funcs_lazy_loader_t : hb_unicode_funcs_lazy_loader_t<hb_glib_unicode_funcs_lazy_loader_t>
{
retry:
hb_unicode_funcs_t *glib_funcs = static_glib_funcs.get ();
if (unlikely (!static_glib_funcs.cmpexch (glib_funcs, nullptr)))
goto retry;
hb_unicode_funcs_destroy (glib_funcs);
}
#endif
hb_unicode_funcs_t *
hb_glib_get_unicode_funcs (void)
{
retry:
hb_unicode_funcs_t *funcs = static_glib_funcs.get ();
if (unlikely (!funcs))
static inline hb_unicode_funcs_t *create (void)
{
funcs = hb_unicode_funcs_create (nullptr);
hb_unicode_funcs_t *funcs = hb_unicode_funcs_create (nullptr);
#define HB_UNICODE_FUNC_IMPLEMENT(name) \
hb_unicode_funcs_set_##name##_func (funcs, hb_glib_unicode_##name, nullptr, nullptr);
@ -396,19 +382,29 @@ retry:
hb_unicode_funcs_make_immutable (funcs);
if (unlikely (!static_glib_funcs.cmpexch (nullptr, funcs)))
{
hb_unicode_funcs_destroy (funcs);
goto retry;
}
#ifdef HB_USE_ATEXIT
atexit (free_static_glib_funcs);
#endif
return funcs;
}
} static_glib_funcs;
#ifdef HB_USE_ATEXIT
atexit (free_static_glib_funcs); /* First person registers atexit() callback. */
#endif
};
return hb_unicode_funcs_reference (funcs);
static
void free_static_glib_funcs (void)
{
static_glib_funcs.fini ();
}
#endif
hb_unicode_funcs_t *
hb_glib_get_unicode_funcs (void)
{
return hb_unicode_funcs_reference (const_cast<hb_unicode_funcs_t *> (static_glib_funcs.get ()));
}
#if GLIB_CHECK_VERSION(2,31,10)

View File

@ -32,6 +32,7 @@
#include "hb-icu.h"
#include "hb-unicode-private.hh"
#include "hb-machinery-private.hh"
#include <unicode/uchar.h>
#include <unicode/unorm2.h>
@ -345,39 +346,13 @@ hb_icu_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs HB_UNUSED,
}
static hb_atomic_ptr_t<hb_unicode_funcs_t> static_icu_funcs;
static void free_static_icu_funcs (void);
#ifdef HB_USE_ATEXIT
static
void free_static_icu_funcs (void)
static struct hb_icu_unicode_funcs_lazy_loader_t : hb_unicode_funcs_lazy_loader_t<hb_icu_unicode_funcs_lazy_loader_t>
{
retry:
hb_unicode_funcs_t *icu_funcs = static_icu_funcs.get ();
if (unlikely (!static_icu_funcs.cmpexch (icu_funcs, nullptr)))
goto retry;
hb_unicode_funcs_destroy (icu_funcs);
}
#endif
hb_unicode_funcs_t *
hb_icu_get_unicode_funcs (void)
{
retry:
hb_unicode_funcs_t *funcs = static_icu_funcs.get ();
if (unlikely (!funcs))
static inline hb_unicode_funcs_t *create (void)
{
#if U_ICU_VERSION_MAJOR_NUM >= 49
if (!normalizer.get ())
{
UErrorCode icu_err = U_ZERO_ERROR;
/* We ignore failure in getNFCInstace(). */
(void) normalizer.cmpexch (nullptr, unorm2_getNFCInstance (&icu_err));
}
#endif
funcs = hb_unicode_funcs_create (nullptr);
hb_unicode_funcs_t *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);
@ -386,16 +361,24 @@ retry:
hb_unicode_funcs_make_immutable (funcs);
if (unlikely (!static_icu_funcs.cmpexch (nullptr, funcs)))
{
hb_unicode_funcs_destroy (funcs);
goto retry;
}
#ifdef HB_USE_ATEXIT
atexit (free_static_icu_funcs);
#endif
return funcs;
}
} static_icu_funcs;
#ifdef HB_USE_ATEXIT
atexit (free_static_icu_funcs); /* First person registers atexit() callback. */
#endif
};
return hb_unicode_funcs_reference (funcs);
static
void free_static_icu_funcs (void)
{
static_icu_funcs.fini ();
}
#endif
hb_unicode_funcs_t *
hb_icu_get_unicode_funcs (void)
{
return hb_unicode_funcs_reference (const_cast<hb_unicode_funcs_t *> (static_icu_funcs.get ()));
}

View File

@ -632,17 +632,17 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData>
Stored *p = instance.get ();
if (unlikely (p && !this->instance.cmpexch (p, nullptr)))
goto retry;
destroy (p);
do_destroy (p);
}
inline Stored * create (void) const
inline Stored * do_create (void) const
{
Stored *p = this->template call_create<Stored, Subclass> ();
if (unlikely (!p))
p = const_cast<Stored *> (Subclass::get_null ());
return p;
}
static inline void destroy (Stored *p)
static inline void do_destroy (Stored *p)
{
if (p && p != Subclass::get_null ())
Subclass::destroy (p);
@ -662,11 +662,11 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData>
Stored *p = this->instance.get ();
if (unlikely (!p))
{
p = create ();
p = do_create ();
assert (p);
if (unlikely (!this->instance.cmpexch (nullptr, p)))
{
destroy (p);
do_destroy (p);
goto retry;
}
}
@ -681,13 +681,14 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData>
Stored *p = this->instance.get ();
if (unlikely (!this->instance.cmpexch (p, instance_)))
goto retry;
destroy (p);
do_destroy (p);
}
inline const Returned * get (void) const { return Subclass::convert (get_stored ()); }
/* To be possibly overloaded by subclasses. */
static inline const Returned* convert (const Stored *p) { return p; }
static inline Returned* convert (Stored *p) { return p; }
static inline const Stored* get_null (void) { return &Null(Stored); }
private:
@ -748,5 +749,20 @@ struct hb_table_lazy_loader_t : hb_lazy_loader_t<hb_table_lazy_loader_t<T, Where
}
};
template <typename Subclass>
struct hb_unicode_funcs_lazy_loader_t : hb_lazy_loader_t<Subclass,
void, 0,
hb_unicode_funcs_t>
{
static inline void destroy (hb_unicode_funcs_t *p)
{
hb_unicode_funcs_destroy (p);
}
static inline const hb_unicode_funcs_t *get_null (void)
{
return hb_unicode_funcs_get_empty ();
}
};
#endif /* HB_MACHINERY_PRIVATE_HH */

View File

@ -17,6 +17,7 @@
#include "hb-private.hh"
#include "hb-unicode-private.hh"
#include "hb-machinery-private.hh"
#include "ucdn.h"
@ -238,31 +239,14 @@ hb_ucdn_decompose_compatibility(hb_unicode_funcs_t *ufuncs HB_UNUSED,
return ucdn_compat_decompose(u, decomposed);
}
static hb_atomic_ptr_t<hb_unicode_funcs_t> static_ucdn_funcs;
#ifdef HB_USE_ATEXIT
static
void free_static_ucdn_funcs (void)
static void free_static_ucdn_funcs (void);
static struct hb_ucdn_unicode_funcs_lazy_loader_t : hb_unicode_funcs_lazy_loader_t<hb_ucdn_unicode_funcs_lazy_loader_t>
{
retry:
hb_unicode_funcs_t *ucdn_funcs = static_ucdn_funcs.get ();
if (unlikely (!static_ucdn_funcs.cmpexch (ucdn_funcs, nullptr)))
goto retry;
hb_unicode_funcs_destroy (ucdn_funcs);
}
#endif
extern "C" HB_INTERNAL
hb_unicode_funcs_t *
hb_ucdn_get_unicode_funcs (void)
{
retry:
hb_unicode_funcs_t *funcs = static_ucdn_funcs.get ();
if (unlikely (!funcs))
static inline hb_unicode_funcs_t *create (void)
{
funcs = hb_unicode_funcs_create (nullptr);
hb_unicode_funcs_t *funcs = hb_unicode_funcs_create (nullptr);
#define HB_UNICODE_FUNC_IMPLEMENT(name) \
hb_unicode_funcs_set_##name##_func (funcs, hb_ucdn_##name, nullptr, nullptr);
@ -271,16 +255,25 @@ retry:
hb_unicode_funcs_make_immutable (funcs);
if (unlikely (!static_ucdn_funcs.cmpexch (nullptr, funcs)))
{
hb_unicode_funcs_destroy (funcs);
goto retry;
}
#ifdef HB_USE_ATEXIT
atexit (free_static_ucdn_funcs);
#endif
return funcs;
}
} static_ucdn_funcs;
#ifdef HB_USE_ATEXIT
atexit (free_static_ucdn_funcs); /* First person registers atexit() callback. */
#endif
};
return hb_unicode_funcs_reference (funcs);
static
void free_static_ucdn_funcs (void)
{
static_ucdn_funcs.fini ();
}
#endif
extern "C" HB_INTERNAL
hb_unicode_funcs_t *
hb_ucdn_get_unicode_funcs (void)
{
return hb_unicode_funcs_reference (const_cast<hb_unicode_funcs_t *> (static_ucdn_funcs.get ()));
}