[glib/ucdn/icu/ft/ot] Make returned funcs inert

Such that client cannot accidentally destroy them, even though that
will be a bug in their code...
This commit is contained in:
Behdad Esfahbod 2017-10-27 16:34:01 -06:00
parent bfa7f37a73
commit 5daf3bd449
6 changed files with 45 additions and 5 deletions

View File

@ -428,6 +428,7 @@ static hb_font_funcs_t *static_ft_funcs = nullptr;
static
void free_static_ft_funcs (void)
{
hb_object_undo_inert (static_ft_funcs);
hb_font_funcs_destroy (static_ft_funcs);
}
#endif
@ -458,8 +459,10 @@ retry:
hb_font_funcs_set_glyph_from_name_func (funcs, hb_ft_get_glyph_from_name, nullptr, nullptr);
hb_font_funcs_make_immutable (funcs);
hb_object_make_inert (funcs);
if (!hb_atomic_ptr_cmpexch (&static_ft_funcs, nullptr, funcs)) {
hb_object_undo_inert (funcs);
hb_font_funcs_destroy (funcs);
goto retry;
}

View File

@ -370,6 +370,7 @@ static hb_unicode_funcs_t *static_glib_funcs = nullptr;
static
void free_static_glib_funcs (void)
{
hb_object_undo_inert (static_glib_funcs);
hb_unicode_funcs_destroy (static_glib_funcs);
}
#endif
@ -390,8 +391,10 @@ retry:
#undef HB_UNICODE_FUNC_IMPLEMENT
hb_unicode_funcs_make_immutable (funcs);
hb_object_make_inert (funcs);
if (!hb_atomic_ptr_cmpexch (&static_glib_funcs, nullptr, funcs)) {
hb_object_undo_inert (funcs);
hb_unicode_funcs_destroy (funcs);
goto retry;
}

View File

@ -351,6 +351,7 @@ static hb_unicode_funcs_t *static_icu_funcs = nullptr;
static
void free_static_icu_funcs (void)
{
hb_object_undo_inert (static_icu_funcs);
hb_unicode_funcs_destroy (static_icu_funcs);
}
#endif
@ -379,8 +380,10 @@ retry:
#undef HB_UNICODE_FUNC_IMPLEMENT
hb_unicode_funcs_make_immutable (funcs);
hb_object_make_inert (funcs);
if (!hb_atomic_ptr_cmpexch (&static_icu_funcs, nullptr, funcs)) {
hb_object_undo_inert (funcs);
hb_unicode_funcs_destroy (funcs);
goto retry;
}

View File

@ -47,9 +47,10 @@
/* reference_count */
#define HB_REFERENCE_COUNT_INERT_VALUE -1
#define HB_REFERENCE_COUNT_POISON_VALUE -0x0000DEAD
#define HB_REFERENCE_COUNT_INIT {HB_ATOMIC_INT_INIT(HB_REFERENCE_COUNT_INERT_VALUE)}
#define HB_REFERENCE_COUNT_UNCHANGABLE_VALUE -0x53043
#define HB_REFERENCE_COUNT_UNREFFABLE_VALUE -0x07734
#define HB_REFERENCE_COUNT_UNTOUCHABLE_VALUE -0xBEDAD
#define HB_REFERENCE_COUNT_INIT {HB_ATOMIC_INT_INIT (HB_REFERENCE_COUNT_UNCHANGABLE_VALUE)}
struct hb_reference_count_t
{
@ -59,9 +60,23 @@ struct hb_reference_count_t
inline int get_unsafe (void) const { return ref_count.get_unsafe (); }
inline int inc (void) { return ref_count.inc (); }
inline int dec (void) { return ref_count.dec (); }
inline void finish (void) { ref_count.set_unsafe (HB_REFERENCE_COUNT_POISON_VALUE); }
inline void finish (void) { ref_count.set_unsafe (HB_REFERENCE_COUNT_UNTOUCHABLE_VALUE); }
inline bool is_inert (void) const { return ref_count.get_unsafe () == HB_REFERENCE_COUNT_INERT_VALUE; }
inline void make_inert (void)
{
if (get_unsafe () == HB_REFERENCE_COUNT_UNCHANGABLE_VALUE)
return;
ref_count.set_unsafe (HB_REFERENCE_COUNT_UNREFFABLE_VALUE);
}
inline void undo_inert (void)
{
if (get_unsafe () == HB_REFERENCE_COUNT_UNCHANGABLE_VALUE)
return;
assert (get_unsafe () == HB_REFERENCE_COUNT_UNREFFABLE_VALUE);
ref_count.set_unsafe (1);
}
inline bool is_inert (void) const { return ref_count.get_unsafe () < 0; }
inline bool is_valid (void) const { return ref_count.get_unsafe () > 0; }
};
@ -152,6 +167,16 @@ static inline bool hb_object_is_valid (const Type *obj)
return likely (obj->header.ref_count.is_valid ());
}
template <typename Type>
static inline void hb_object_make_inert (Type *obj)
{
obj->header.ref_count.make_inert ();
}
template <typename Type>
static inline void hb_object_undo_inert (Type *obj)
{
obj->header.ref_count.undo_inert ();
}
template <typename Type>
static inline Type *hb_object_reference (Type *obj)
{
hb_object_trace (obj, HB_FUNC);

View File

@ -628,6 +628,7 @@ static hb_font_funcs_t *static_ot_funcs = nullptr;
static
void free_static_ot_funcs (void)
{
hb_object_undo_inert (static_ot_funcs);
hb_font_funcs_destroy (static_ot_funcs);
}
#endif
@ -658,8 +659,10 @@ retry:
hb_font_funcs_set_glyph_from_name_func (funcs, hb_ot_get_glyph_from_name, nullptr, nullptr);
hb_font_funcs_make_immutable (funcs);
hb_object_make_inert (funcs);
if (!hb_atomic_ptr_cmpexch (&static_ot_funcs, nullptr, funcs)) {
hb_object_undo_inert (funcs);
hb_font_funcs_destroy (funcs);
goto retry;
}

View File

@ -237,6 +237,7 @@ static hb_unicode_funcs_t *static_ucdn_funcs = nullptr;
static
void free_static_ucdn_funcs (void)
{
hb_object_undo_inert (static_ucdn_funcs);
hb_unicode_funcs_destroy (static_ucdn_funcs);
}
#endif
@ -258,8 +259,10 @@ retry:
#undef HB_UNICODE_FUNC_IMPLEMENT
hb_unicode_funcs_make_immutable (funcs);
hb_object_make_inert (funcs);
if (!hb_atomic_ptr_cmpexch (&static_ucdn_funcs, nullptr, funcs)) {
hb_object_undo_inert (funcs);
hb_unicode_funcs_destroy (funcs);
goto retry;
}