[ucdn/glib/icu] Port unicode_funcs statics to lazy-loader
This commit is contained in:
parent
1b6b481262
commit
cb3fc3685c
@ -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)
|
||||
|
||||
|
@ -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 ()));
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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 ()));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user