56#ifndef IMQUIC_REFCOUNT_H
57#define IMQUIC_REFCOUNT_H
71#define imquic_refcount_containerof(refptr, type, member) \
72 ((type *)((char *)(refptr) - offsetof(type, member)))
84#ifdef IMQUIC_REFCOUNT_DEBUG
86extern GHashTable *imquic_counters;
88#define imquic_refcount_track(refp) { \
89 imquic_mutex_lock(&imquic_counters_mutex); \
90 if(imquic_counters == NULL) \
91 imquic_counters = g_hash_table_new(NULL, NULL); \
92 g_hash_table_insert(imquic_counters, refp, refp); \
93 imquic_mutex_unlock(&imquic_counters_mutex); \
95#define imquic_refcount_untrack(refp) { \
96 imquic_mutex_lock(&imquic_counters_mutex); \
97 g_hash_table_remove(imquic_counters, refp); \
98 imquic_mutex_unlock(&imquic_counters_mutex); \
109#define imquic_refcount_init(refp, free_fn) { \
110 if(!imquic_refcount_debug) { \
111 imquic_refcount_init_nodebug(refp, free_fn); \
113 imquic_refcount_init_debug(refp, free_fn); \
122#ifdef IMQUIC_REFCOUNT_DEBUG
123#define imquic_refcount_init_nodebug(refp, free_fn) { \
125 (refp)->free = free_fn; \
126 imquic_refcount_track((refp)); \
129#define imquic_refcount_init_nodebug(refp, free_fn) { \
131 (refp)->free = free_fn; \
140#ifdef IMQUIC_REFCOUNT_DEBUG
141#define imquic_refcount_init_debug(refp, free_fn) { \
143 IMQUIC_PRINT("[%s:%s:%d:init] %p (%d)\n", __FILE__, __FUNCTION__, __LINE__, refp, (refp)->count); \
144 (refp)->free = free_fn; \
145 imquic_refcount_track((refp)); \
148#define imquic_refcount_init_debug(refp, free_fn) { \
150 IMQUIC_PRINT("[%s:%s:%d:init] %p (%d)\n", __FILE__, __FUNCTION__, __LINE__, refp, (refp)->count); \
151 (refp)->free = free_fn; \
157#define imquic_refcount_increase(refp) { \
158 if(!imquic_refcount_debug) { \
159 imquic_refcount_increase_nodebug(refp); \
161 imquic_refcount_increase_debug(refp); \
166#define imquic_refcount_increase_nodebug(refp) { \
167 g_atomic_int_inc((gint *)&(refp)->count); \
171#define imquic_refcount_increase_debug(refp) { \
172 IMQUIC_PRINT("[%s:%s:%d:increase] %p (%d)\n", __FILE__, __FUNCTION__, __LINE__, refp, (refp)->count+1); \
173 g_atomic_int_inc((gint *)&(refp)->count); \
179#define imquic_refcount_decrease(refp) { \
180 if(!imquic_refcount_debug) { \
181 imquic_refcount_decrease_nodebug(refp); \
183 imquic_refcount_decrease_debug(refp); \
189#ifdef IMQUIC_REFCOUNT_DEBUG
190#define imquic_refcount_decrease_debug(refp) { \
191 IMQUIC_PRINT("[%s:%s:%d:decrease] %p (%d)\n", __FILE__, __FUNCTION__, __LINE__, refp, (refp)->count-1); \
192 if(g_atomic_int_dec_and_test((gint *)&(refp)->count)) { \
193 (refp)->free(refp); \
194 imquic_refcount_untrack((refp)); \
198#define imquic_refcount_decrease_debug(refp) { \
199 IMQUIC_PRINT("[%s:%s:%d:decrease] %p (%d)\n", __FILE__, __FUNCTION__, __LINE__, refp, (refp)->count-1); \
200 if(g_atomic_int_dec_and_test((gint *)&(refp)->count)) { \
201 (refp)->free(refp); \
208#ifdef IMQUIC_REFCOUNT_DEBUG
209#define imquic_refcount_decrease_nodebug(refp) { \
210 if(g_atomic_int_dec_and_test((gint *)&(refp)->count)) { \
211 (refp)->free(refp); \
212 imquic_refcount_untrack((refp)); \
216#define imquic_refcount_decrease_nodebug(refp) { \
217 if(g_atomic_int_dec_and_test((gint *)&(refp)->count)) { \
218 (refp)->free(refp); \
Semaphores, Mutexes and Conditions.
GMutex imquic_mutex
imquic mutex implementation
Definition mutex.h:18
int imquic_refcount_debug
Definition imquic.c:30
void(* free)(const imquic_refcount *)
Pointer to the function that will be used to free the object.
Definition refcount.h:81
gint count
The reference counter itself.
Definition refcount.h:79