[ucdn/glib/icu] Port unicode_funcs statics to lazy-loader
authorBehdad Esfahbod <behdad@behdad.org>
Sun, 12 Aug 2018 20:39:01 +0000 (13:39 -0700)
committerBehdad Esfahbod <behdad@behdad.org>
Sun, 12 Aug 2018 20:39:01 +0000 (13:39 -0700)
src/hb-glib.cc
src/hb-icu.cc
src/hb-machinery-private.hh
src/hb-ucdn.cc

index 4bb6f08..a5a82d4 100644 (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)
-{
-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);
@@ -396,20 +382,30 @@ 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. */
+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
index ce58de0..99e3d2c 100644 (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)
-{
-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);
@@ -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. */
+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 ()));
 }
index 1eeae4b..873596d 100644 (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 */
index b414b1d..c58db05 100644 (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)
-{
-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);
@@ -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. */
+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 ()));
 }