Loading...
Searching...
No Matches
refcount.h
Go to the documentation of this file.
#ifndef JANUS_REFCOUNT_H
#define JANUS_REFCOUNT_H
#include <glib.h>
#include "mutex.h"
//~ #define REFCOUNT_DEBUG
extern int refcount_debug;
#define janus_refcount_containerof(refptr, type, member) \
((type *)((char *)(refptr) - offsetof(type, member)))
typedef struct janus_refcount janus_refcount;
struct janus_refcount {
gint count;
void (*free)(const janus_refcount *);
};
#ifdef REFCOUNT_DEBUG
/* Reference counters debugging */
extern GHashTable *counters;
extern janus_mutex counters_mutex;
#define janus_refcount_track(refp) { \
janus_mutex_lock(&counters_mutex); \
if(counters == NULL) \
counters = g_hash_table_new(NULL, NULL); \
g_hash_table_insert(counters, refp, refp); \
janus_mutex_unlock(&counters_mutex); \
}
#define janus_refcount_untrack(refp) { \
janus_mutex_lock(&counters_mutex); \
g_hash_table_remove(counters, refp); \
janus_mutex_unlock(&counters_mutex); \
}
#endif
#define janus_refcount_init(refp, free_fn) { \
if(!refcount_debug) { \
janus_refcount_init_nodebug(refp, free_fn); \
} else { \
janus_refcount_init_debug(refp, free_fn); \
} \
}
#ifdef REFCOUNT_DEBUG
#define janus_refcount_init_nodebug(refp, free_fn) { \
(refp)->count = 1; \
(refp)->free = free_fn; \
janus_refcount_track((refp)); \
}
#else
#define janus_refcount_init_nodebug(refp, free_fn) { \
(refp)->count = 1; \
(refp)->free = free_fn; \
}
#endif
#ifdef REFCOUNT_DEBUG
#define janus_refcount_init_debug(refp, free_fn) { \
(refp)->count = 1; \
JANUS_PRINT("[%s:%s:%d:init] %p (%d)\n", __FILE__, __FUNCTION__, __LINE__, refp, (refp)->count); \
(refp)->free = free_fn; \
janus_refcount_track((refp)); \
}
#else
#define janus_refcount_init_debug(refp, free_fn) { \
(refp)->count = 1; \
JANUS_PRINT("[%s:%s:%d:init] %p (%d)\n", __FILE__, __FUNCTION__, __LINE__, refp, (refp)->count); \
(refp)->free = free_fn; \
}
#endif
#define janus_refcount_increase(refp) { \
if(!refcount_debug) { \
janus_refcount_increase_nodebug(refp); \
} else { \
janus_refcount_increase_debug(refp); \
} \
}
#define janus_refcount_increase_nodebug(refp) { \
g_atomic_int_inc((gint *)&(refp)->count); \
}
#define janus_refcount_increase_debug(refp) { \
JANUS_PRINT("[%s:%s:%d:increase] %p (%d)\n", __FILE__, __FUNCTION__, __LINE__, refp, (refp)->count+1); \
g_atomic_int_inc((gint *)&(refp)->count); \
}
#define janus_refcount_decrease(refp) { \
if(!refcount_debug) { \
janus_refcount_decrease_nodebug(refp); \
} else { \
janus_refcount_decrease_debug(refp); \
} \
}
#ifdef REFCOUNT_DEBUG
#define janus_refcount_decrease_debug(refp) { \
JANUS_PRINT("[%s:%s:%d:decrease] %p (%d)\n", __FILE__, __FUNCTION__, __LINE__, refp, (refp)->count-1); \
if(g_atomic_int_dec_and_test((gint *)&(refp)->count)) { \
(refp)->free(refp); \
janus_refcount_untrack((refp)); \
} \
}
#else
#define janus_refcount_decrease_debug(refp) { \
JANUS_PRINT("[%s:%s:%d:decrease] %p (%d)\n", __FILE__, __FUNCTION__, __LINE__, refp, (refp)->count-1); \
if(g_atomic_int_dec_and_test((gint *)&(refp)->count)) { \
(refp)->free(refp); \
} \
}
#endif
#ifdef REFCOUNT_DEBUG
#define janus_refcount_decrease_nodebug(refp) { \
if(g_atomic_int_dec_and_test((gint *)&(refp)->count)) { \
(refp)->free(refp); \
janus_refcount_untrack((refp)); \
} \
}
#else
#define janus_refcount_decrease_nodebug(refp) { \
if(g_atomic_int_dec_and_test((gint *)&(refp)->count)) { \
(refp)->free(refp); \
} \
}
#endif
#endif
refcount_debug
int refcount_debug
Definition janus.c:517
mutex.h
Semaphores, Mutexes and Conditions.
janus_mutex
GMutex janus_mutex
Janus mutex implementation.
Definition mutex.h:73
janus_refcount
Definition refcount.h:78
janus_refcount::count
gint count
The reference counter itself.
Definition refcount.h:80
janus_refcount::free
void(* free)(const janus_refcount *)
Pointer to the function that will be used to free the object.
Definition refcount.h:82