Loading...
Searching...
No Matches
refcount.h
Go to the documentation of this file.
1
56#ifndef IMQUIC_REFCOUNT_H
57#define IMQUIC_REFCOUNT_H
58
59#include <glib.h>
60#include "mutex.h"
61
62//~ #define IMQUIC_REFCOUNT_DEBUG
63
64extern int imquic_refcount_debug;
65
71#define imquic_refcount_containerof(refptr, type, member) \
72 ((type *)((char *)(refptr) - offsetof(type, member)))
73
74
79 gint count;
81 void (*free)(const imquic_refcount *);
82};
83
84#ifdef IMQUIC_REFCOUNT_DEBUG
85/* Reference counters debugging */
86extern GHashTable *imquic_counters;
87extern imquic_mutex imquic_counters_mutex;
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); \
94}
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); \
99}
100#endif
101
102
109#define imquic_refcount_init(refp, free_fn) { \
110 if(!imquic_refcount_debug) { \
111 imquic_refcount_init_nodebug(refp, free_fn); \
112 } else { \
113 imquic_refcount_init_debug(refp, free_fn); \
114 } \
115}
122#ifdef IMQUIC_REFCOUNT_DEBUG
123#define imquic_refcount_init_nodebug(refp, free_fn) { \
124 (refp)->count = 1; \
125 (refp)->free = free_fn; \
126 imquic_refcount_track((refp)); \
127}
128#else
129#define imquic_refcount_init_nodebug(refp, free_fn) { \
130 (refp)->count = 1; \
131 (refp)->free = free_fn; \
132}
133#endif
140#ifdef IMQUIC_REFCOUNT_DEBUG
141#define imquic_refcount_init_debug(refp, free_fn) { \
142 (refp)->count = 1; \
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)); \
146}
147#else
148#define imquic_refcount_init_debug(refp, free_fn) { \
149 (refp)->count = 1; \
150 IMQUIC_PRINT("[%s:%s:%d:init] %p (%d)\n", __FILE__, __FUNCTION__, __LINE__, refp, (refp)->count); \
151 (refp)->free = free_fn; \
152}
153#endif
154
157#define imquic_refcount_increase(refp) { \
158 if(!imquic_refcount_debug) { \
159 imquic_refcount_increase_nodebug(refp); \
160 } else { \
161 imquic_refcount_increase_debug(refp); \
162 } \
163}
166#define imquic_refcount_increase_nodebug(refp) { \
167 g_atomic_int_inc((gint *)&(refp)->count); \
168}
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); \
174}
175
179#define imquic_refcount_decrease(refp) { \
180 if(!imquic_refcount_debug) { \
181 imquic_refcount_decrease_nodebug(refp); \
182 } else { \
183 imquic_refcount_decrease_debug(refp); \
184 } \
185}
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)); \
195 } \
196}
197#else
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); \
202 } \
203}
204#endif
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)); \
213 } \
214}
215#else
216#define imquic_refcount_decrease_nodebug(refp) { \
217 if(g_atomic_int_dec_and_test((gint *)&(refp)->count)) { \
218 (refp)->free(refp); \
219 } \
220}
221#endif
222
223#endif
Semaphores, Mutexes and Conditions.
GMutex imquic_mutex
imquic mutex implementation
Definition mutex.h:18
int imquic_refcount_debug
Definition imquic.c:30
Definition refcount.h:77
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