Chromium Code Reviews| 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 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 61 inline bool is_invalid (void) const { return ref_count == HB_REFERENCE_COUNT_I NVALID_VALUE; } | 61 inline bool is_invalid (void) const { return ref_count == HB_REFERENCE_COUNT_I NVALID_VALUE; } |
| 62 | 62 |
| 63 }; | 63 }; |
| 64 | 64 |
| 65 | 65 |
| 66 /* user_data */ | 66 /* user_data */ |
| 67 | 67 |
| 68 #define HB_USER_DATA_ARRAY_INIT {HB_MUTEX_INIT, HB_LOCKABLE_SET_INIT} | 68 #define HB_USER_DATA_ARRAY_INIT {HB_MUTEX_INIT, HB_LOCKABLE_SET_INIT} |
| 69 struct hb_user_data_array_t | 69 struct hb_user_data_array_t |
| 70 { | 70 { |
| 71 /* TODO Add tracing. */ | |
| 72 | |
| 73 struct hb_user_data_item_t { | 71 struct hb_user_data_item_t { |
| 74 hb_user_data_key_t *key; | 72 hb_user_data_key_t *key; |
| 75 void *data; | 73 void *data; |
| 76 hb_destroy_func_t destroy; | 74 hb_destroy_func_t destroy; |
| 77 | 75 |
| 78 inline bool operator == (hb_user_data_key_t *other_key) const { return key = = other_key; } | 76 inline bool operator == (hb_user_data_key_t *other_key) const { return key = = other_key; } |
| 79 inline bool operator == (hb_user_data_item_t &other) const { return key == o ther.key; } | 77 inline bool operator == (hb_user_data_item_t &other) const { return key == o ther.key; } |
| 80 | 78 |
| 81 void finish (void) { if (destroy) destroy (data); } | 79 void finish (void) { if (destroy) destroy (data); } |
| 82 }; | 80 }; |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 99 | 97 |
| 100 /* object_header */ | 98 /* object_header */ |
| 101 | 99 |
| 102 struct hb_object_header_t | 100 struct hb_object_header_t |
| 103 { | 101 { |
| 104 hb_reference_count_t ref_count; | 102 hb_reference_count_t ref_count; |
| 105 hb_user_data_array_t user_data; | 103 hb_user_data_array_t user_data; |
| 106 | 104 |
| 107 #define HB_OBJECT_HEADER_STATIC {HB_REFERENCE_COUNT_INVALID, HB_USER_DATA_ARRAY_ INIT} | 105 #define HB_OBJECT_HEADER_STATIC {HB_REFERENCE_COUNT_INVALID, HB_USER_DATA_ARRAY_ INIT} |
| 108 | 106 |
| 109 static inline void *create (unsigned int size) { | |
| 110 hb_object_header_t *obj = (hb_object_header_t *) calloc (1, size); | |
| 111 | |
| 112 if (likely (obj)) | |
| 113 obj->init (); | |
| 114 | |
| 115 return obj; | |
| 116 } | |
| 117 | |
| 118 inline void init (void) { | |
| 119 ref_count.init (1); | |
| 120 user_data.init (); | |
| 121 } | |
| 122 | |
| 123 inline bool is_inert (void) const { | |
| 124 return unlikely (ref_count.is_invalid ()); | |
| 125 } | |
| 126 | |
| 127 inline void reference (void) { | |
| 128 if (unlikely (!this || this->is_inert ())) | |
| 129 return; | |
| 130 ref_count.inc (); | |
| 131 } | |
| 132 | |
| 133 inline bool destroy (void) { | |
| 134 if (unlikely (!this || this->is_inert ())) | |
| 135 return false; | |
| 136 if (ref_count.dec () != 1) | |
| 137 return false; | |
| 138 | |
| 139 ref_count.finish (); /* Do this before user_data */ | |
| 140 user_data.finish (); | |
| 141 | |
| 142 return true; | |
| 143 } | |
| 144 | |
| 145 inline bool set_user_data (hb_user_data_key_t *key, | |
| 146 void * data, | |
| 147 hb_destroy_func_t destroy_func, | |
| 148 hb_bool_t replace) { | |
| 149 if (unlikely (!this || this->is_inert ())) | |
| 150 return false; | |
| 151 | |
| 152 return user_data.set (key, data, destroy_func, replace); | |
| 153 } | |
| 154 | |
| 155 inline void *get_user_data (hb_user_data_key_t *key) { | |
| 156 if (unlikely (!this || this->is_inert ())) | |
| 157 return NULL; | |
| 158 | |
| 159 return user_data.get (key); | |
| 160 } | |
| 161 | |
| 162 inline void trace (const char *function) const { | |
| 163 if (unlikely (!this)) return; | |
| 164 /* TODO We cannot use DEBUG_MSG_FUNC here since that one currently only | |
| 165 * prints the class name and throws away the template info. */ | |
| 166 DEBUG_MSG (OBJECT, (void *) this, | |
| 167 "%s refcount=%d", | |
| 168 function, | |
| 169 this ? ref_count.ref_count : 0); | |
| 170 } | |
| 171 | |
| 172 private: | 107 private: |
| 173 ASSERT_POD (); | 108 ASSERT_POD (); |
| 174 }; | 109 }; |
| 175 | 110 |
| 176 | 111 |
| 177 /* object */ | 112 /* object */ |
| 178 | 113 |
| 179 template <typename Type> | 114 template <typename Type> |
| 180 static inline void hb_object_trace (const Type *obj, const char *function) | 115 static inline void hb_object_trace (const Type *obj, const char *function) |
| 181 { | 116 { |
| 182 obj->header.trace (function); | 117 DEBUG_MSG (OBJECT, (void *) obj, |
| 118 » "%s refcount=%d", | |
|
Nico
2014/08/17 04:15:27
(looks like someone added tabs here, you might wan
| |
| 119 » function, | |
| 120 » obj ? obj->header.ref_count.ref_count : 0); | |
| 183 } | 121 } |
| 122 | |
| 184 template <typename Type> | 123 template <typename Type> |
| 185 static inline Type *hb_object_create (void) | 124 static inline Type *hb_object_create (void) |
| 186 { | 125 { |
| 187 Type *obj = (Type *) hb_object_header_t::create (sizeof (Type)); | 126 Type *obj = (Type *) calloc (1, sizeof (Type)); |
| 127 | |
| 128 if (unlikely (!obj)) | |
| 129 return obj; | |
| 130 | |
| 131 hb_object_init (obj); | |
| 188 hb_object_trace (obj, HB_FUNC); | 132 hb_object_trace (obj, HB_FUNC); |
| 189 return obj; | 133 return obj; |
| 190 } | 134 } |
| 191 template <typename Type> | 135 template <typename Type> |
| 136 static inline void hb_object_init (Type *obj) | |
| 137 { | |
| 138 obj->header.ref_count.init (1); | |
| 139 obj->header.user_data.init (); | |
| 140 } | |
| 141 template <typename Type> | |
| 192 static inline bool hb_object_is_inert (const Type *obj) | 142 static inline bool hb_object_is_inert (const Type *obj) |
| 193 { | 143 { |
| 194 return unlikely (obj->header.is_inert ()); | 144 return unlikely (obj->header.ref_count.is_invalid ()); |
| 195 } | 145 } |
| 196 template <typename Type> | 146 template <typename Type> |
| 197 static inline Type *hb_object_reference (Type *obj) | 147 static inline Type *hb_object_reference (Type *obj) |
| 198 { | 148 { |
| 199 hb_object_trace (obj, HB_FUNC); | 149 hb_object_trace (obj, HB_FUNC); |
| 200 obj->header.reference (); | 150 if (unlikely (!obj || hb_object_is_inert (obj))) |
| 151 return obj; | |
| 152 obj->header.ref_count.inc (); | |
| 201 return obj; | 153 return obj; |
| 202 } | 154 } |
| 203 template <typename Type> | 155 template <typename Type> |
| 204 static inline bool hb_object_destroy (Type *obj) | 156 static inline bool hb_object_destroy (Type *obj) |
| 205 { | 157 { |
| 206 hb_object_trace (obj, HB_FUNC); | 158 hb_object_trace (obj, HB_FUNC); |
| 207 return obj->header.destroy (); | 159 if (unlikely (!obj || hb_object_is_inert (obj))) |
| 160 return false; | |
| 161 if (obj->header.ref_count.dec () != 1) | |
| 162 return false; | |
| 163 | |
| 164 obj->header.ref_count.finish (); /* Do this before user_data */ | |
| 165 obj->header.user_data.finish (); | |
| 166 return true; | |
| 208 } | 167 } |
| 209 template <typename Type> | 168 template <typename Type> |
| 210 static inline bool hb_object_set_user_data (Type *obj, | 169 static inline bool hb_object_set_user_data (Type *obj, |
| 211 hb_user_data_key_t *key, | 170 hb_user_data_key_t *key, |
| 212 void * data, | 171 void * data, |
| 213 hb_destroy_func_t destroy, | 172 hb_destroy_func_t destroy, |
| 214 hb_bool_t replace) | 173 hb_bool_t replace) |
| 215 { | 174 { |
| 216 return obj->header.set_user_data (key, data, destroy, replace); | 175 if (unlikely (!obj || hb_object_is_inert (obj))) |
| 176 return false; | |
| 177 return obj->header.user_data.set (key, data, destroy, replace); | |
| 217 } | 178 } |
| 218 | 179 |
| 219 template <typename Type> | 180 template <typename Type> |
| 220 static inline void *hb_object_get_user_data (Type *obj, | 181 static inline void *hb_object_get_user_data (Type *obj, |
| 221 hb_user_data_key_t *key) | 182 hb_user_data_key_t *key) |
| 222 { | 183 { |
| 223 return obj->header.get_user_data (key); | 184 if (unlikely (!obj || hb_object_is_inert (obj))) |
| 185 return NULL; | |
| 186 return obj->header.user_data.get (key); | |
| 224 } | 187 } |
| 225 | 188 |
| 226 | 189 |
| 227 #endif /* HB_OBJECT_PRIVATE_HH */ | 190 #endif /* HB_OBJECT_PRIVATE_HH */ |
| OLD | NEW |