#include "hb-glib.h"
#include "hb-unicode-private.hh"
+#include "hb-machinery-private.hh"
#if !GLIB_CHECK_VERSION(2,29,14)
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)
-{
-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
+static void free_static_glib_funcs (void);
-hb_unicode_funcs_t *
-hb_glib_get_unicode_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 *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);
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. */
+static
+void free_static_glib_funcs (void)
+{
+ static_glib_funcs.fini ();
+}
#endif
- };
- return hb_unicode_funcs_reference (funcs);
+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)
static void
#include "hb-icu.h"
#include "hb-unicode-private.hh"
+#include "hb-machinery-private.hh"
#include <unicode/uchar.h>
#include <unicode/unorm2.h>
}
-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)
-{
-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)
+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 *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);
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. */
+static
+void free_static_icu_funcs (void)
+{
+ static_icu_funcs.fini ();
+}
#endif
- };
- return hb_unicode_funcs_reference (funcs);
+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 ()));
}
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);
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;
}
}
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:
}
};
+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 */
#include "hb-private.hh"
#include "hb-unicode-private.hh"
+#include "hb-machinery-private.hh"
#include "ucdn.h"
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)
-{
-retry:
- hb_unicode_funcs_t *ucdn_funcs = static_ucdn_funcs.get ();
- if (unlikely (!static_ucdn_funcs.cmpexch (ucdn_funcs, nullptr)))
- goto retry;
+static void free_static_ucdn_funcs (void);
- hb_unicode_funcs_destroy (ucdn_funcs);
-}
-#endif
-
-extern "C" HB_INTERNAL
-hb_unicode_funcs_t *
-hb_ucdn_get_unicode_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 *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);
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. */
+static
+void free_static_ucdn_funcs (void)
+{
+ static_ucdn_funcs.fini ();
+}
#endif
- };
- return hb_unicode_funcs_reference (funcs);
+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 ()));
}