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 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
96 | 96 |
97 HB_INTERNAL void finish (hb_mutex_t &lock); | 97 HB_INTERNAL void finish (hb_mutex_t &lock); |
98 }; | 98 }; |
99 | 99 |
100 | 100 |
101 /* object_header */ | 101 /* object_header */ |
102 | 102 |
103 struct hb_object_header_t | 103 struct hb_object_header_t |
104 { | 104 { |
105 hb_reference_count_t ref_count; | 105 hb_reference_count_t ref_count; |
106 hb_mutex_t lock; | 106 hb_mutex_t mutex; |
107 hb_user_data_array_t user_data; | 107 hb_user_data_array_t user_data; |
108 | 108 |
109 #define HB_OBJECT_HEADER_STATIC {HB_REFERENCE_COUNT_INVALID, HB_MUTEX_INIT, HB_U
SER_DATA_ARRAY_INIT} | 109 #define HB_OBJECT_HEADER_STATIC {HB_REFERENCE_COUNT_INVALID, HB_MUTEX_INIT, HB_U
SER_DATA_ARRAY_INIT} |
110 | 110 |
111 static inline void *create (unsigned int size) { | 111 static inline void *create (unsigned int size) { |
112 hb_object_header_t *obj = (hb_object_header_t *) calloc (1, size); | 112 hb_object_header_t *obj = (hb_object_header_t *) calloc (1, size); |
113 | 113 |
114 if (likely (obj)) | 114 if (likely (obj)) |
115 obj->init (); | 115 obj->init (); |
116 | 116 |
117 return obj; | 117 return obj; |
118 } | 118 } |
119 | 119 |
120 inline void init (void) { | 120 inline void init (void) { |
121 ref_count.init (1); | 121 ref_count.init (1); |
122 lock.init (); | 122 mutex.init (); |
123 user_data.init (); | 123 user_data.init (); |
124 } | 124 } |
125 | 125 |
126 inline bool is_inert (void) const { | 126 inline bool is_inert (void) const { |
127 return unlikely (ref_count.is_invalid ()); | 127 return unlikely (ref_count.is_invalid ()); |
128 } | 128 } |
129 | 129 |
130 inline void reference (void) { | 130 inline void reference (void) { |
131 if (unlikely (!this || this->is_inert ())) | 131 if (unlikely (!this || this->is_inert ())) |
132 return; | 132 return; |
133 ref_count.inc (); | 133 ref_count.inc (); |
134 } | 134 } |
135 | 135 |
136 inline bool destroy (void) { | 136 inline bool destroy (void) { |
137 if (unlikely (!this || this->is_inert ())) | 137 if (unlikely (!this || this->is_inert ())) |
138 return false; | 138 return false; |
139 if (ref_count.dec () != 1) | 139 if (ref_count.dec () != 1) |
140 return false; | 140 return false; |
141 | 141 |
142 ref_count.finish (); /* Do this before user_data */ | 142 ref_count.finish (); /* Do this before user_data */ |
143 user_data.finish (lock); | 143 user_data.finish (mutex); |
144 lock.finish (); | 144 mutex.finish (); |
145 | 145 |
146 return true; | 146 return true; |
147 } | 147 } |
148 | 148 |
| 149 inline void lock (void) { |
| 150 mutex.lock (); |
| 151 } |
| 152 |
| 153 inline void unlock (void) { |
| 154 mutex.unlock (); |
| 155 } |
| 156 |
149 inline bool set_user_data (hb_user_data_key_t *key, | 157 inline bool set_user_data (hb_user_data_key_t *key, |
150 void * data, | 158 void * data, |
151 hb_destroy_func_t destroy_func, | 159 hb_destroy_func_t destroy_func, |
152 hb_bool_t replace) { | 160 hb_bool_t replace) { |
153 if (unlikely (!this || this->is_inert ())) | 161 if (unlikely (!this || this->is_inert ())) |
154 return false; | 162 return false; |
155 | 163 |
156 return user_data.set (key, data, destroy_func, replace, lock); | 164 return user_data.set (key, data, destroy_func, replace, mutex); |
157 } | 165 } |
158 | 166 |
159 inline void *get_user_data (hb_user_data_key_t *key) { | 167 inline void *get_user_data (hb_user_data_key_t *key) { |
160 if (unlikely (!this || this->is_inert ())) | 168 if (unlikely (!this || this->is_inert ())) |
161 return NULL; | 169 return NULL; |
162 | 170 |
163 return user_data.get (key, lock); | 171 return user_data.get (key, mutex); |
164 } | 172 } |
165 | 173 |
166 inline void trace (const char *function) const { | 174 inline void trace (const char *function) const { |
167 if (unlikely (!this)) return; | 175 if (unlikely (!this)) return; |
168 /* XXX We cannot use DEBUG_MSG_FUNC here since that one currecntly only | 176 /* TODO We cannot use DEBUG_MSG_FUNC here since that one currently only |
169 * prints the class name and throws away the template info. */ | 177 * prints the class name and throws away the template info. */ |
170 DEBUG_MSG (OBJECT, (void *) this, | 178 DEBUG_MSG (OBJECT, (void *) this, |
171 "%s refcount=%d", | 179 "%s refcount=%d", |
172 function, | 180 function, |
173 this ? ref_count.ref_count : 0); | 181 this ? ref_count.ref_count : 0); |
174 } | 182 } |
175 | 183 |
176 private: | 184 private: |
177 ASSERT_POD (); | 185 ASSERT_POD (); |
178 }; | 186 }; |
(...skipping 25 matching lines...) Expand all Loading... |
204 obj->header.reference (); | 212 obj->header.reference (); |
205 return obj; | 213 return obj; |
206 } | 214 } |
207 template <typename Type> | 215 template <typename Type> |
208 static inline bool hb_object_destroy (Type *obj) | 216 static inline bool hb_object_destroy (Type *obj) |
209 { | 217 { |
210 hb_object_trace (obj, HB_FUNC); | 218 hb_object_trace (obj, HB_FUNC); |
211 return obj->header.destroy (); | 219 return obj->header.destroy (); |
212 } | 220 } |
213 template <typename Type> | 221 template <typename Type> |
| 222 static inline void hb_object_lock (Type *obj) |
| 223 { |
| 224 hb_object_trace (obj, HB_FUNC); |
| 225 return obj->header.lock (); |
| 226 } |
| 227 template <typename Type> |
| 228 static inline void hb_object_unlock (Type *obj) |
| 229 { |
| 230 hb_object_trace (obj, HB_FUNC); |
| 231 return obj->header.unlock (); |
| 232 } |
| 233 template <typename Type> |
214 static inline bool hb_object_set_user_data (Type *obj, | 234 static inline bool hb_object_set_user_data (Type *obj, |
215 hb_user_data_key_t *key, | 235 hb_user_data_key_t *key, |
216 void * data, | 236 void * data, |
217 hb_destroy_func_t destroy, | 237 hb_destroy_func_t destroy, |
218 hb_bool_t replace) | 238 hb_bool_t replace) |
219 { | 239 { |
220 return obj->header.set_user_data (key, data, destroy, replace); | 240 return obj->header.set_user_data (key, data, destroy, replace); |
221 } | 241 } |
222 | 242 |
223 template <typename Type> | 243 template <typename Type> |
224 static inline void *hb_object_get_user_data (Type *obj, | 244 static inline void *hb_object_get_user_data (Type *obj, |
225 hb_user_data_key_t *key) | 245 hb_user_data_key_t *key) |
226 { | 246 { |
227 return obj->header.get_user_data (key); | 247 return obj->header.get_user_data (key); |
228 } | 248 } |
229 | 249 |
230 | 250 |
231 #endif /* HB_OBJECT_PRIVATE_HH */ | 251 #endif /* HB_OBJECT_PRIVATE_HH */ |
OLD | NEW |