|
|
|
@ -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<hb_atomic_int_t &> (ref_count) = v; } |
|
|
|
|
inline void init (int v) { ref_count = v; } |
|
|
|
|
inline int inc (void) { return hb_atomic_int_add (const_cast<hb_atomic_int_t &> (ref_count), 1); } |
|
|
|
|
inline int dec (void) { return hb_atomic_int_add (const_cast<hb_atomic_int_t &> (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<hb_user_data_item_t, hb_static_mutex_t> items; |
|
|
|
|
hb_lockable_set_t<hb_user_data_item_t, hb_mutex_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 { |
|
|
|
|