Add hb_lazy_table_loader_t
authorBehdad Esfahbod <behdad@behdad.org>
Tue, 10 Jan 2017 06:45:25 +0000 (22:45 -0800)
committerBehdad Esfahbod <behdad@behdad.org>
Tue, 10 Jan 2017 06:47:47 +0000 (22:47 -0800)
src/hb-open-type-private.hh

index a8756d4..6ee4fae 100644 (file)
@@ -30,6 +30,7 @@
 #define HB_OPEN_TYPE_PRIVATE_HH
 
 #include "hb-private.hh"
+#include "hb-face-private.hh"
 
 
 namespace OT {
@@ -1107,6 +1108,45 @@ struct hb_lazy_loader_t
   T *instance;
 };
 
+template <typename T>
+struct hb_lazy_table_loader_t
+{
+  inline void init (hb_face_t *face_)
+  {
+    face = face_;
+    instance = NULL;
+    blob = NULL;
+  }
+
+  inline void fini (void)
+  {
+    hb_blob_destroy (blob);
+  }
+
+  inline const T* operator-> (void) const
+  {
+  retry:
+    T *p = (T *) hb_atomic_ptr_get (&instance);
+    if (unlikely (!p))
+    {
+      hb_blob_t *blob_ = OT::Sanitizer<T>::sanitize (face->reference_table (T::tableTag));
+      p = OT::Sanitizer<T>::lock_instance (blob);
+      if (!hb_atomic_ptr_cmpexch (const_cast<T **>(&instance), NULL, p))
+      {
+       hb_blob_destroy (blob_);
+       goto retry;
+      }
+      blob = blob_;
+    }
+    return p;
+  }
+
+  private:
+  hb_face_t *face;
+  T *instance;
+  hb_blob_t *blob;
+};
+
 
 } /* namespace OT */