[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-glib.h"
|
||||||
|
|
||||||
#include "hb-unicode-private.hh"
|
#include "hb-unicode-private.hh"
|
||||||
|
#include "hb-machinery-private.hh"
|
||||||
|
|
||||||
|
|
||||||
#if !GLIB_CHECK_VERSION(2,29,14)
|
#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;
|
return utf8_decomposed_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static hb_atomic_ptr_t<hb_unicode_funcs_t> static_glib_funcs;
|
|
||||||
|
|
||||||
#ifdef HB_USE_ATEXIT
|
|
||||||
static
|
static void free_static_glib_funcs (void);
|
||||||
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:
|
static inline hb_unicode_funcs_t *create (void)
|
||||||
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))
|
|
||||||
{
|
{
|
||||||
funcs = hb_unicode_funcs_create (nullptr);
|
hb_unicode_funcs_t *funcs = hb_unicode_funcs_create (nullptr);
|
||||||
|
|
||||||
#define HB_UNICODE_FUNC_IMPLEMENT(name) \
|
#define HB_UNICODE_FUNC_IMPLEMENT(name) \
|
||||||
hb_unicode_funcs_set_##name##_func (funcs, hb_glib_unicode_##name, nullptr, nullptr);
|
hb_unicode_funcs_set_##name##_func (funcs, hb_glib_unicode_##name, nullptr, nullptr);
|
||||||
@ -396,19 +382,29 @@ retry:
|
|||||||
|
|
||||||
hb_unicode_funcs_make_immutable (funcs);
|
hb_unicode_funcs_make_immutable (funcs);
|
||||||
|
|
||||||
if (unlikely (!static_glib_funcs.cmpexch (nullptr, funcs)))
|
#ifdef HB_USE_ATEXIT
|
||||||
{
|
atexit (free_static_glib_funcs);
|
||||||
hb_unicode_funcs_destroy (funcs);
|
#endif
|
||||||
goto retry;
|
|
||||||
}
|
return funcs;
|
||||||
|
}
|
||||||
|
} static_glib_funcs;
|
||||||
|
|
||||||
#ifdef HB_USE_ATEXIT
|
#ifdef HB_USE_ATEXIT
|
||||||
atexit (free_static_glib_funcs); /* First person registers atexit() callback. */
|
static
|
||||||
#endif
|
void free_static_glib_funcs (void)
|
||||||
};
|
{
|
||||||
|
static_glib_funcs.fini ();
|
||||||
return hb_unicode_funcs_reference (funcs);
|
|
||||||
}
|
}
|
||||||
|
#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)
|
#if GLIB_CHECK_VERSION(2,31,10)
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
#include "hb-icu.h"
|
#include "hb-icu.h"
|
||||||
|
|
||||||
#include "hb-unicode-private.hh"
|
#include "hb-unicode-private.hh"
|
||||||
|
#include "hb-machinery-private.hh"
|
||||||
|
|
||||||
#include <unicode/uchar.h>
|
#include <unicode/uchar.h>
|
||||||
#include <unicode/unorm2.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 struct hb_icu_unicode_funcs_lazy_loader_t : hb_unicode_funcs_lazy_loader_t<hb_icu_unicode_funcs_lazy_loader_t>
|
||||||
static
|
|
||||||
void free_static_icu_funcs (void)
|
|
||||||
{
|
{
|
||||||
retry:
|
static inline hb_unicode_funcs_t *create (void)
|
||||||
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))
|
|
||||||
{
|
{
|
||||||
#if U_ICU_VERSION_MAJOR_NUM >= 49
|
hb_unicode_funcs_t *funcs = hb_unicode_funcs_create (nullptr);
|
||||||
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);
|
|
||||||
|
|
||||||
#define HB_UNICODE_FUNC_IMPLEMENT(name) \
|
#define HB_UNICODE_FUNC_IMPLEMENT(name) \
|
||||||
hb_unicode_funcs_set_##name##_func (funcs, hb_icu_unicode_##name, nullptr, nullptr);
|
hb_unicode_funcs_set_##name##_func (funcs, hb_icu_unicode_##name, nullptr, nullptr);
|
||||||
@ -386,16 +361,24 @@ retry:
|
|||||||
|
|
||||||
hb_unicode_funcs_make_immutable (funcs);
|
hb_unicode_funcs_make_immutable (funcs);
|
||||||
|
|
||||||
if (unlikely (!static_icu_funcs.cmpexch (nullptr, funcs)))
|
#ifdef HB_USE_ATEXIT
|
||||||
{
|
atexit (free_static_icu_funcs);
|
||||||
hb_unicode_funcs_destroy (funcs);
|
#endif
|
||||||
goto retry;
|
|
||||||
}
|
return funcs;
|
||||||
|
}
|
||||||
|
} static_icu_funcs;
|
||||||
|
|
||||||
#ifdef HB_USE_ATEXIT
|
#ifdef HB_USE_ATEXIT
|
||||||
atexit (free_static_icu_funcs); /* First person registers atexit() callback. */
|
static
|
||||||
#endif
|
void free_static_icu_funcs (void)
|
||||||
};
|
{
|
||||||
|
static_icu_funcs.fini ();
|
||||||
return hb_unicode_funcs_reference (funcs);
|
}
|
||||||
|
#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 ();
|
Stored *p = instance.get ();
|
||||||
if (unlikely (p && !this->instance.cmpexch (p, nullptr)))
|
if (unlikely (p && !this->instance.cmpexch (p, nullptr)))
|
||||||
goto retry;
|
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> ();
|
Stored *p = this->template call_create<Stored, Subclass> ();
|
||||||
if (unlikely (!p))
|
if (unlikely (!p))
|
||||||
p = const_cast<Stored *> (Subclass::get_null ());
|
p = const_cast<Stored *> (Subclass::get_null ());
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
static inline void destroy (Stored *p)
|
static inline void do_destroy (Stored *p)
|
||||||
{
|
{
|
||||||
if (p && p != Subclass::get_null ())
|
if (p && p != Subclass::get_null ())
|
||||||
Subclass::destroy (p);
|
Subclass::destroy (p);
|
||||||
@ -662,11 +662,11 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData>
|
|||||||
Stored *p = this->instance.get ();
|
Stored *p = this->instance.get ();
|
||||||
if (unlikely (!p))
|
if (unlikely (!p))
|
||||||
{
|
{
|
||||||
p = create ();
|
p = do_create ();
|
||||||
assert (p);
|
assert (p);
|
||||||
if (unlikely (!this->instance.cmpexch (nullptr, p)))
|
if (unlikely (!this->instance.cmpexch (nullptr, p)))
|
||||||
{
|
{
|
||||||
destroy (p);
|
do_destroy (p);
|
||||||
goto retry;
|
goto retry;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -681,13 +681,14 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData>
|
|||||||
Stored *p = this->instance.get ();
|
Stored *p = this->instance.get ();
|
||||||
if (unlikely (!this->instance.cmpexch (p, instance_)))
|
if (unlikely (!this->instance.cmpexch (p, instance_)))
|
||||||
goto retry;
|
goto retry;
|
||||||
destroy (p);
|
do_destroy (p);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const Returned * get (void) const { return Subclass::convert (get_stored ()); }
|
inline const Returned * get (void) const { return Subclass::convert (get_stored ()); }
|
||||||
|
|
||||||
/* To be possibly overloaded by subclasses. */
|
/* To be possibly overloaded by subclasses. */
|
||||||
static inline const Returned* convert (const Stored *p) { return p; }
|
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); }
|
static inline const Stored* get_null (void) { return &Null(Stored); }
|
||||||
|
|
||||||
private:
|
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 */
|
#endif /* HB_MACHINERY_PRIVATE_HH */
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include "hb-private.hh"
|
#include "hb-private.hh"
|
||||||
|
|
||||||
#include "hb-unicode-private.hh"
|
#include "hb-unicode-private.hh"
|
||||||
|
#include "hb-machinery-private.hh"
|
||||||
|
|
||||||
#include "ucdn.h"
|
#include "ucdn.h"
|
||||||
|
|
||||||
@ -238,31 +239,14 @@ 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_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:
|
static inline hb_unicode_funcs_t *create (void)
|
||||||
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))
|
|
||||||
{
|
{
|
||||||
funcs = hb_unicode_funcs_create (nullptr);
|
hb_unicode_funcs_t *funcs = hb_unicode_funcs_create (nullptr);
|
||||||
|
|
||||||
#define HB_UNICODE_FUNC_IMPLEMENT(name) \
|
#define HB_UNICODE_FUNC_IMPLEMENT(name) \
|
||||||
hb_unicode_funcs_set_##name##_func (funcs, hb_ucdn_##name, nullptr, nullptr);
|
hb_unicode_funcs_set_##name##_func (funcs, hb_ucdn_##name, nullptr, nullptr);
|
||||||
@ -271,16 +255,25 @@ retry:
|
|||||||
|
|
||||||
hb_unicode_funcs_make_immutable (funcs);
|
hb_unicode_funcs_make_immutable (funcs);
|
||||||
|
|
||||||
if (unlikely (!static_ucdn_funcs.cmpexch (nullptr, funcs)))
|
#ifdef HB_USE_ATEXIT
|
||||||
{
|
atexit (free_static_ucdn_funcs);
|
||||||
hb_unicode_funcs_destroy (funcs);
|
#endif
|
||||||
goto retry;
|
|
||||||
}
|
return funcs;
|
||||||
|
}
|
||||||
|
} static_ucdn_funcs;
|
||||||
|
|
||||||
#ifdef HB_USE_ATEXIT
|
#ifdef HB_USE_ATEXIT
|
||||||
atexit (free_static_ucdn_funcs); /* First person registers atexit() callback. */
|
static
|
||||||
#endif
|
void free_static_ucdn_funcs (void)
|
||||||
};
|
{
|
||||||
|
static_ucdn_funcs.fini ();
|
||||||
return hb_unicode_funcs_reference (funcs);
|
}
|
||||||
|
#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