From 0e253e97af71e2a7ead153589f61fd579a247502 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 5 Jun 2012 15:37:19 -0400 Subject: [PATCH] Add a mutex to object header Removes one more static-initialization. A few more to go. --- src/hb-common.cc | 24 +++++++++--------------- src/hb-mutex-private.hh | 19 +++++++------------ src/hb-object-private.hh | 36 ++++++++++++++++++++++-------------- src/hb-private.hh | 11 +++++------ 4 files changed, 43 insertions(+), 47 deletions(-) diff --git a/src/hb-common.cc b/src/hb-common.cc index bfbba65..c7ee9af 100644 --- a/src/hb-common.cc +++ b/src/hb-common.cc @@ -314,47 +314,41 @@ hb_script_get_horizontal_direction (hb_script_t script) /* hb_user_data_array_t */ - -/* NOTE: Currently we use a global lock for user_data access - * threadsafety. If one day we add a mutex to any object, we - * should switch to using that insted for these too. - */ - -static hb_static_mutex_t user_data_lock; - bool hb_user_data_array_t::set (hb_user_data_key_t *key, void * data, hb_destroy_func_t destroy, - hb_bool_t replace) + hb_bool_t replace, + hb_mutex_t &lock) { if (!key) return false; if (replace) { if (!data && !destroy) { - items.remove (key, user_data_lock); + items.remove (key, lock); return true; } } hb_user_data_item_t item = {key, data, destroy}; - bool ret = !!items.replace_or_insert (item, user_data_lock, replace); + bool ret = !!items.replace_or_insert (item, lock, replace); return ret; } void * -hb_user_data_array_t::get (hb_user_data_key_t *key) +hb_user_data_array_t::get (hb_user_data_key_t *key, + hb_mutex_t &lock) { hb_user_data_item_t item = {NULL }; - return items.find (key, &item, user_data_lock) ? item.data : NULL; + return items.find (key, &item, lock) ? item.data : NULL; } void -hb_user_data_array_t::finish (void) +hb_user_data_array_t::finish (hb_mutex_t &lock) { - items.finish (user_data_lock); + items.finish (lock); } diff --git a/src/hb-mutex-private.hh b/src/hb-mutex-private.hh index 44b48df..9e061b9 100644 --- a/src/hb-mutex-private.hh +++ b/src/hb-mutex-private.hh @@ -50,7 +50,7 @@ typedef CRITICAL_SECTION hb_mutex_impl_t; #define hb_mutex_impl_init(M) InitializeCriticalSection (M) #define hb_mutex_impl_lock(M) EnterCriticalSection (M) #define hb_mutex_impl_unlock(M) LeaveCriticalSection (M) -#define hb_mutex_impl_free(M) DeleteCriticalSection (M) +#define hb_mutex_impl_finish(M) DeleteCriticalSection (M) #elif !defined(HB_NO_MT) && defined(__APPLE__) @@ -61,7 +61,7 @@ typedef pthread_mutex_t hb_mutex_impl_t; #define hb_mutex_impl_init(M) pthread_mutex_init (M, NULL) #define hb_mutex_impl_lock(M) pthread_mutex_lock (M) #define hb_mutex_impl_unlock(M) pthread_mutex_unlock (M) -#define hb_mutex_impl_free(M) pthread_mutex_destroy (M) +#define hb_mutex_impl_finish(M) pthread_mutex_destroy (M) #elif !defined(HB_NO_MT) && defined(HAVE_GLIB) @@ -72,7 +72,7 @@ typedef GStaticMutex hb_mutex_impl_t; #define hb_mutex_impl_init(M) g_static_mutex_init (M) #define hb_mutex_impl_lock(M) g_static_mutex_lock (M) #define hb_mutex_impl_unlock(M) g_static_mutex_unlock (M) -#define hb_mutex_impl_free(M) g_static_mutex_free (M) +#define hb_mutex_impl_finish(M) g_static_mutex_free (M) #else @@ -83,11 +83,12 @@ typedef volatile int hb_mutex_impl_t; #define hb_mutex_impl_init(M) ((void) (*(M) = 0)) #define hb_mutex_impl_lock(M) ((void) (*(M) = 1)) #define hb_mutex_impl_unlock(M) ((void) (*(M) = 0)) -#define hb_mutex_impl_free(M) ((void) (*(M) = 2)) +#define hb_mutex_impl_finish(M) ((void) (*(M) = 2)) #endif +#define HB_MUTEX_INIT {HB_MUTEX_IMPL_INIT} struct hb_mutex_t { hb_mutex_impl_t m; @@ -95,20 +96,14 @@ struct hb_mutex_t inline void init (void) { hb_mutex_impl_init (&m); } inline void lock (void) { hb_mutex_impl_lock (&m); } inline void unlock (void) { hb_mutex_impl_unlock (&m); } - inline void free (void) { hb_mutex_impl_free (&m); } + inline void finish (void) { hb_mutex_impl_finish (&m); } }; -#define HB_MUTEX_INIT {HB_MUTEX_IMPL_INIT} -#define hb_mutex_init(M) (M)->init () -#define hb_mutex_lock(M) (M)->lock () -#define hb_mutex_unlock(M) (M)->unlock () -#define hb_mutex_free(M) (M)->free () - struct hb_static_mutex_t : hb_mutex_t { hb_static_mutex_t (void) { this->init (); } - ~hb_static_mutex_t (void) { this->free (); } + ~hb_static_mutex_t (void) { this->finish (); } private: NO_COPY (hb_static_mutex_t); diff --git a/src/hb-object-private.hh b/src/hb-object-private.hh index 8a2cdb6..cad4426 100644 --- a/src/hb-object-private.hh +++ b/src/hb-object-private.hh @@ -47,16 +47,16 @@ /* reference_count */ +#define HB_REFERENCE_COUNT_INVALID_VALUE ((hb_atomic_int_t) -1) +#define HB_REFERENCE_COUNT_INVALID {HB_REFERENCE_COUNT_INVALID_VALUE} struct hb_reference_count_t { hb_atomic_int_t ref_count; -#define HB_REFERENCE_COUNT_INVALID_VALUE ((hb_atomic_int_t) -1) -#define HB_REFERENCE_COUNT_INVALID {HB_REFERENCE_COUNT_INVALID_VALUE} - - inline void init (int v) { const_cast (ref_count) = v; } + inline void init (int v) { ref_count = v; } inline int inc (void) { return hb_atomic_int_add (const_cast (ref_count), 1); } inline int dec (void) { return hb_atomic_int_add (const_cast (ref_count), -1); } + inline void finish (void) { ref_count = HB_REFERENCE_COUNT_INVALID_VALUE; } inline bool is_invalid (void) const { return ref_count == HB_REFERENCE_COUNT_INVALID_VALUE; } @@ -65,6 +65,7 @@ struct hb_reference_count_t /* user_data */ +#define HB_USER_DATA_ARRAY_INIT {HB_LOCKABLE_SET_INIT} struct hb_user_data_array_t { struct hb_user_data_item_t { @@ -78,18 +79,20 @@ struct hb_user_data_array_t void finish (void) { if (destroy) destroy (data); } }; - hb_lockable_set_t items; + hb_lockable_set_t items; inline void init (void) { items.init (); } HB_INTERNAL bool set (hb_user_data_key_t *key, void * data, hb_destroy_func_t destroy, - hb_bool_t replace); + hb_bool_t replace, + hb_mutex_t &lock); - HB_INTERNAL void *get (hb_user_data_key_t *key); + HB_INTERNAL void *get (hb_user_data_key_t *key, + hb_mutex_t &lock); - HB_INTERNAL void finish (void); + HB_INTERNAL void finish (hb_mutex_t &lock); }; @@ -98,9 +101,10 @@ struct hb_user_data_array_t struct hb_object_header_t { hb_reference_count_t ref_count; + hb_mutex_t lock; hb_user_data_array_t user_data; -#define HB_OBJECT_HEADER_STATIC {HB_REFERENCE_COUNT_INVALID} +#define HB_OBJECT_HEADER_STATIC {HB_REFERENCE_COUNT_INVALID, HB_MUTEX_INIT, HB_USER_DATA_ARRAY_INIT} static inline void *create (unsigned int size) { hb_object_header_t *obj = (hb_object_header_t *) calloc (1, size); @@ -113,6 +117,7 @@ struct hb_object_header_t inline void init (void) { ref_count.init (1); + lock.init (); user_data.init (); } @@ -132,9 +137,9 @@ struct hb_object_header_t if (ref_count.dec () != 1) return false; - ref_count.init (HB_REFERENCE_COUNT_INVALID_VALUE); - - user_data.finish (); + ref_count.finish (); /* Do this before user_data */ + user_data.finish (lock); + lock.finish (); return true; } @@ -146,11 +151,14 @@ struct hb_object_header_t if (unlikely (!this || this->is_inert ())) return false; - return user_data.set (key, data, destroy_func, replace); + return user_data.set (key, data, destroy_func, replace, lock); } inline void *get_user_data (hb_user_data_key_t *key) { - return user_data.get (key); + if (unlikely (!this || this->is_inert ())) + return NULL; + + return user_data.get (key, lock); } inline void trace (const char *function) const { diff --git a/src/hb-private.hh b/src/hb-private.hh index d18b8fb..4a61661 100644 --- a/src/hb-private.hh +++ b/src/hb-private.hh @@ -239,9 +239,10 @@ typedef int (*hb_compare_func_t) (const void *, const void *); /* arrays and maps */ +#define HB_PREALLOCED_ARRAY_INIT {0} template -struct hb_prealloced_array_t { - +struct hb_prealloced_array_t +{ unsigned int len; unsigned int allocated; Type *array; @@ -342,14 +343,12 @@ struct hb_prealloced_array_t { } }; -template -struct hb_array_t : hb_prealloced_array_t {}; - +#define HB_LOCKABLE_SET_INIT {HB_PREALLOCED_ARRAY_INIT} template struct hb_lockable_set_t { - hb_array_t items; + hb_prealloced_array_t items; inline void init (void) { items.init (); } -- 2.7.4