| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright © 2007 Chris Wilson | 2 * Copyright © 2007 Chris Wilson |
| 3 * Copyright © 2009,2010 Red Hat, Inc. | 3 * Copyright © 2009,2010 Red Hat, Inc. |
| 4 * Copyright © 2011,2012 Google, Inc. | 4 * Copyright © 2011,2012 Google, Inc. |
| 5 * | 5 * |
| 6 * This is part of HarfBuzz, a text shaping library. | 6 * This is part of HarfBuzz, a text shaping library. |
| 7 * | 7 * |
| 8 * Permission is hereby granted, without written agreement and without | 8 * Permission is hereby granted, without written agreement and without |
| 9 * license or royalty fees, to use, copy, modify, and distribute this | 9 * license or royalty fees, to use, copy, modify, and distribute this |
| 10 * software and its documentation for any purpose, provided that the | 10 * software and its documentation for any purpose, provided that the |
| (...skipping 29 matching lines...) Expand all Loading... |
| 40 | 40 |
| 41 /* Debug */ | 41 /* Debug */ |
| 42 | 42 |
| 43 #ifndef HB_DEBUG_OBJECT | 43 #ifndef HB_DEBUG_OBJECT |
| 44 #define HB_DEBUG_OBJECT (HB_DEBUG+0) | 44 #define HB_DEBUG_OBJECT (HB_DEBUG+0) |
| 45 #endif | 45 #endif |
| 46 | 46 |
| 47 | 47 |
| 48 /* reference_count */ | 48 /* reference_count */ |
| 49 | 49 |
| 50 #define HB_REFERENCE_COUNT_INVALID_VALUE -1 | 50 #define HB_REFERENCE_COUNT_INERT_VALUE -1 |
| 51 #define HB_REFERENCE_COUNT_INIT {HB_ATOMIC_INT_INIT(HB_REFERENCE_COUNT_INVALID_V
ALUE)} | 51 #define HB_REFERENCE_COUNT_POISON_VALUE -0x0000DEAD |
| 52 #define HB_REFERENCE_COUNT_INIT {HB_ATOMIC_INT_INIT(HB_REFERENCE_COUNT_INERT_VAL
UE)} |
| 52 | 53 |
| 53 struct hb_reference_count_t | 54 struct hb_reference_count_t |
| 54 { | 55 { |
| 55 hb_atomic_int_t ref_count; | 56 hb_atomic_int_t ref_count; |
| 56 | 57 |
| 57 inline void init (int v) { ref_count.set_unsafe (v); } | 58 inline void init (int v) { ref_count.set_unsafe (v); } |
| 58 inline int get_unsafe (void) const { return ref_count.get_unsafe (); } | 59 inline int get_unsafe (void) const { return ref_count.get_unsafe (); } |
| 59 inline int inc (void) { return ref_count.inc (); } | 60 inline int inc (void) { return ref_count.inc (); } |
| 60 inline int dec (void) { return ref_count.dec (); } | 61 inline int dec (void) { return ref_count.dec (); } |
| 61 inline void finish (void) { ref_count.set_unsafe (HB_REFERENCE_COUNT_INVALID_V
ALUE); } | 62 inline void finish (void) { ref_count.set_unsafe (HB_REFERENCE_COUNT_POISON_VA
LUE); } |
| 62 | 63 |
| 63 inline bool is_invalid (void) const { return ref_count.get_unsafe () == HB_REF
ERENCE_COUNT_INVALID_VALUE; } | 64 inline bool is_inert (void) const { return ref_count.get_unsafe () == HB_REFER
ENCE_COUNT_INERT_VALUE; } |
| 65 inline bool is_valid (void) const { return ref_count.get_unsafe () > 0; } |
| 64 }; | 66 }; |
| 65 | 67 |
| 66 | 68 |
| 67 /* user_data */ | 69 /* user_data */ |
| 68 | 70 |
| 69 #define HB_USER_DATA_ARRAY_INIT {HB_MUTEX_INIT, HB_LOCKABLE_SET_INIT} | 71 #define HB_USER_DATA_ARRAY_INIT {HB_MUTEX_INIT, HB_LOCKABLE_SET_INIT} |
| 70 struct hb_user_data_array_t | 72 struct hb_user_data_array_t |
| 71 { | 73 { |
| 72 struct hb_user_data_item_t { | 74 struct hb_user_data_item_t { |
| 73 hb_user_data_key_t *key; | 75 hb_user_data_key_t *key; |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 135 } | 137 } |
| 136 template <typename Type> | 138 template <typename Type> |
| 137 static inline void hb_object_init (Type *obj) | 139 static inline void hb_object_init (Type *obj) |
| 138 { | 140 { |
| 139 obj->header.ref_count.init (1); | 141 obj->header.ref_count.init (1); |
| 140 obj->header.user_data.init (); | 142 obj->header.user_data.init (); |
| 141 } | 143 } |
| 142 template <typename Type> | 144 template <typename Type> |
| 143 static inline bool hb_object_is_inert (const Type *obj) | 145 static inline bool hb_object_is_inert (const Type *obj) |
| 144 { | 146 { |
| 145 return unlikely (obj->header.ref_count.is_invalid ()); | 147 return unlikely (obj->header.ref_count.is_inert ()); |
| 148 } |
| 149 template <typename Type> |
| 150 static inline bool hb_object_is_valid (const Type *obj) |
| 151 { |
| 152 return likely (obj->header.ref_count.is_valid ()); |
| 146 } | 153 } |
| 147 template <typename Type> | 154 template <typename Type> |
| 148 static inline Type *hb_object_reference (Type *obj) | 155 static inline Type *hb_object_reference (Type *obj) |
| 149 { | 156 { |
| 150 hb_object_trace (obj, HB_FUNC); | 157 hb_object_trace (obj, HB_FUNC); |
| 151 if (unlikely (!obj || hb_object_is_inert (obj))) | 158 if (unlikely (!obj || hb_object_is_inert (obj))) |
| 152 return obj; | 159 return obj; |
| 160 assert (hb_object_is_valid (obj)); |
| 153 obj->header.ref_count.inc (); | 161 obj->header.ref_count.inc (); |
| 154 return obj; | 162 return obj; |
| 155 } | 163 } |
| 156 template <typename Type> | 164 template <typename Type> |
| 157 static inline bool hb_object_destroy (Type *obj) | 165 static inline bool hb_object_destroy (Type *obj) |
| 158 { | 166 { |
| 159 hb_object_trace (obj, HB_FUNC); | 167 hb_object_trace (obj, HB_FUNC); |
| 160 if (unlikely (!obj || hb_object_is_inert (obj))) | 168 if (unlikely (!obj || hb_object_is_inert (obj))) |
| 161 return false; | 169 return false; |
| 170 assert (hb_object_is_valid (obj)); |
| 162 if (obj->header.ref_count.dec () != 1) | 171 if (obj->header.ref_count.dec () != 1) |
| 163 return false; | 172 return false; |
| 164 | 173 |
| 165 obj->header.ref_count.finish (); /* Do this before user_data */ | 174 obj->header.ref_count.finish (); /* Do this before user_data */ |
| 166 obj->header.user_data.finish (); | 175 obj->header.user_data.finish (); |
| 167 return true; | 176 return true; |
| 168 } | 177 } |
| 169 template <typename Type> | 178 template <typename Type> |
| 170 static inline bool hb_object_set_user_data (Type *obj, | 179 static inline bool hb_object_set_user_data (Type *obj, |
| 171 hb_user_data_key_t *key, | 180 hb_user_data_key_t *key, |
| 172 void * data, | 181 void * data, |
| 173 hb_destroy_func_t destroy, | 182 hb_destroy_func_t destroy, |
| 174 hb_bool_t replace) | 183 hb_bool_t replace) |
| 175 { | 184 { |
| 176 if (unlikely (!obj || hb_object_is_inert (obj))) | 185 if (unlikely (!obj || hb_object_is_inert (obj))) |
| 177 return false; | 186 return false; |
| 187 assert (hb_object_is_valid (obj)); |
| 178 return obj->header.user_data.set (key, data, destroy, replace); | 188 return obj->header.user_data.set (key, data, destroy, replace); |
| 179 } | 189 } |
| 180 | 190 |
| 181 template <typename Type> | 191 template <typename Type> |
| 182 static inline void *hb_object_get_user_data (Type *obj, | 192 static inline void *hb_object_get_user_data (Type *obj, |
| 183 hb_user_data_key_t *key) | 193 hb_user_data_key_t *key) |
| 184 { | 194 { |
| 185 if (unlikely (!obj || hb_object_is_inert (obj))) | 195 if (unlikely (!obj || hb_object_is_inert (obj))) |
| 186 return NULL; | 196 return NULL; |
| 197 assert (hb_object_is_valid (obj)); |
| 187 return obj->header.user_data.get (key); | 198 return obj->header.user_data.get (key); |
| 188 } | 199 } |
| 189 | 200 |
| 190 | 201 |
| 191 #endif /* HB_OBJECT_PRIVATE_HH */ | 202 #endif /* HB_OBJECT_PRIVATE_HH */ |
| OLD | NEW |