From ebbcc1112229cde9ed469efdfeac7ef79dfcd834 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 9 Jan 2017 22:45:25 -0800 Subject: [PATCH] Add hb_lazy_table_loader_t --- src/hb-open-type-private.hh | 40 +++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh index a8756d466..6ee4fae9e 100644 --- a/src/hb-open-type-private.hh +++ b/src/hb-open-type-private.hh @@ -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 +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::sanitize (face->reference_table (T::tableTag)); + p = OT::Sanitizer::lock_instance (blob); + if (!hb_atomic_ptr_cmpexch (const_cast(&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 */