[lazy] Port more to it
authorBehdad Esfahbod <behdad@behdad.org>
Mon, 13 Aug 2018 00:14:32 +0000 (17:14 -0700)
committerBehdad Esfahbod <behdad@behdad.org>
Mon, 13 Aug 2018 00:14:32 +0000 (17:14 -0700)
src/hb-shape.cc

index 01734f8..22a2020 100644 (file)
@@ -32,6 +32,7 @@
 #include "hb-shape-plan-private.hh"
 #include "hb-buffer-private.hh"
 #include "hb-font-private.hh"
+#include "hb-machinery-private.hh"
 
 /**
  * SECTION:hb-shape
  * contains the output glyphs and their positions.
  **/
 
-static hb_atomic_ptr_t <const char **> static_shaper_list;
+
+static void free_static_shaper_list (void);
+
+static struct hb_shaper_list_lazy_loader_t : hb_lazy_loader_t<const char *,
+                                                            hb_shaper_list_lazy_loader_t>
+{
+  static inline const char ** create (void)
+  {
+    const char **shaper_list = (const char **) calloc (1 + HB_SHAPERS_COUNT, sizeof (const char *));
+    if (unlikely (!shaper_list))
+      return nullptr;
+
+    const hb_shaper_pair_t *shapers = _hb_shapers_get ();
+    unsigned int i;
+    for (i = 0; i < HB_SHAPERS_COUNT; i++)
+      shaper_list[i] = shapers[i].name;
+    shaper_list[i] = nullptr;
+
+#ifdef HB_USE_ATEXIT
+    atexit (free_static_shaper_list);
+#endif
+
+    return shaper_list;
+  }
+  static inline void destroy (const char **l)
+  {
+    ::free (l);
+  }
+  static inline const char ** get_null (void)
+  {
+    static const char *nil_shaper_list[] = {nullptr};
+    return nil_shaper_list;
+  }
+} static_shaper_list;
 
 #ifdef HB_USE_ATEXIT
 static
 void free_static_shaper_list (void)
 {
-retry:
-  const char **shaper_list = static_shaper_list.get ();
-  if (unlikely (!static_shaper_list.cmpexch (shaper_list, nullptr)))
-    goto retry;
-
-  free (shaper_list);
+  static_shaper_list.free ();
 }
 #endif
 
+
 /**
  * hb_shape_list_shapers:
  *
@@ -73,36 +103,7 @@ retry:
 const char **
 hb_shape_list_shapers (void)
 {
-retry:
-  const char **shaper_list = static_shaper_list.get ();
-
-  if (unlikely (!shaper_list))
-  {
-    /* Not found; allocate one. */
-    shaper_list = (const char **) calloc (1 + HB_SHAPERS_COUNT, sizeof (const char *));
-    if (unlikely (!shaper_list)) {
-      static const char *nil_shaper_list[] = {nullptr};
-      return nil_shaper_list;
-    }
-
-    const hb_shaper_pair_t *shapers = _hb_shapers_get ();
-    unsigned int i;
-    for (i = 0; i < HB_SHAPERS_COUNT; i++)
-      shaper_list[i] = shapers[i].name;
-    shaper_list[i] = nullptr;
-
-    if (unlikely (!static_shaper_list.cmpexch (nullptr, shaper_list)))
-    {
-      free (shaper_list);
-      goto retry;
-    }
-
-#ifdef HB_USE_ATEXIT
-    atexit (free_static_shaper_list); /* First person registers atexit() callback. */
-#endif
-  }
-
-  return shaper_list;
+  return static_shaper_list.get_unconst ();
 }