[lazy] Use for ft_library
authorBehdad Esfahbod <behdad@behdad.org>
Sun, 12 Aug 2018 23:20:11 +0000 (16:20 -0700)
committerBehdad Esfahbod <behdad@behdad.org>
Sun, 12 Aug 2018 23:20:11 +0000 (16:20 -0700)
src/hb-ft.cc
src/hb-glib.cc
src/hb-icu.cc
src/hb-machinery-private.hh
src/hb-ot-font.cc
src/hb-ucdn.cc

index 5ac9a3e..eea2da1 100644 (file)
@@ -461,7 +461,7 @@ void free_static_ft_funcs (void)
 static hb_font_funcs_t *
 _hb_ft_get_font_funcs (void)
 {
-  return const_cast<hb_font_funcs_t *> (static_ft_funcs.get ());
+  return static_ft_funcs.get_unconst ();
 }
 
 static void
@@ -683,47 +683,46 @@ hb_ft_font_create_referenced (FT_Face ft_face)
 }
 
 
-/* Thread-safe, lock-free, FT_Library */
+static void free_static_ft_library (void);
 
-static hb_atomic_ptr_t<FT_Library> ft_library;
+static struct hb_ft_library_lazy_loader_t : hb_lazy_loader_t<hb_ft_library_lazy_loader_t,
+                                                            void, 0,
+                                                            hb_remove_ptr_t<FT_Library>::value>
+{
+  static inline FT_Library create (void)
+  {
+    FT_Library l;
+    if (FT_Init_FreeType (&l))
+      return nullptr;
+
+#ifdef HB_USE_ATEXIT
+    atexit (free_static_ft_library);
+#endif
+
+    return l;
+  }
+  static inline void destroy (FT_Library l)
+  {
+    FT_Done_FreeType (l);
+  }
+  static inline const FT_Library get_null (void)
+  {
+    return nullptr;
+  }
+} static_ft_library;
 
 #ifdef HB_USE_ATEXIT
 static
-void free_ft_library (void)
+void free_static_ft_library (void)
 {
-retry:
-  FT_Library library = ft_library.get ();
-  if (unlikely (!ft_library.cmpexch (library, nullptr)))
-    goto retry;
-
-  FT_Done_FreeType (library);
+  static_ft_library.free ();
 }
 #endif
 
 static FT_Library
 get_ft_library (void)
 {
-retry:
-  FT_Library library = ft_library.get ();
-
-  if (unlikely (!library))
-  {
-    /* Not found; allocate one. */
-    if (FT_Init_FreeType (&library))
-      return nullptr;
-
-    if (unlikely (!ft_library.cmpexch (nullptr, library)))
-    {
-      FT_Done_FreeType (library);
-      goto retry;
-    }
-
-#ifdef HB_USE_ATEXIT
-    atexit (free_ft_library); /* First person registers atexit() callback. */
-#endif
-  }
-
-  return library;
+  return static_ft_library.get_unconst ();
 }
 
 static void
index 6ce9a35..af7a0fd 100644 (file)
@@ -401,7 +401,7 @@ void free_static_glib_funcs (void)
 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 ()));
+  return hb_unicode_funcs_reference (static_glib_funcs.get_unconst ());
 }
 
 
index 0442d92..7b2c4d6 100644 (file)
@@ -380,5 +380,5 @@ void free_static_icu_funcs (void)
 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 ()));
+  return hb_unicode_funcs_reference (static_icu_funcs.get_unconst ());
 }
index 6221fe5..3c1181b 100644 (file)
@@ -667,7 +667,6 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData>
     if (unlikely (!p))
     {
       p = do_create ();
-      assert (p);
       if (unlikely (!this->instance.cmpexch (nullptr, p)))
       {
         do_destroy (p);
@@ -689,6 +688,7 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData>
   }
 
   inline const Returned * get (void) const { return Subclass::convert (get_stored ()); }
+  inline Returned * get_unconst (void) const { return const_cast<Returned *> (Subclass::convert (get_stored ())); }
 
   /* To be possibly overloaded by subclasses. */
   static inline const Returned* convert (const Stored *p) { return p; }
index f181b07..cac1809 100644 (file)
@@ -271,7 +271,7 @@ void free_static_ot_funcs (void)
 static hb_font_funcs_t *
 _hb_ot_get_font_funcs (void)
 {
-  return const_cast<hb_font_funcs_t *> (static_ot_funcs.get ());
+  return static_ot_funcs.get_unconst ();
 }
 
 
index 1945a1c..6b1bb80 100644 (file)
@@ -275,5 +275,5 @@ 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 ()));
+  return hb_unicode_funcs_reference (static_ucdn_funcs.get_unconst ());
 }