degesch: get rid of repeating refcounting code
Macros aren't exactly spectacular but they work.
This commit is contained in:
parent
635c28820d
commit
5632eecd42
87
degesch.c
87
degesch.c
|
@ -100,12 +100,43 @@ static struct config_item g_config_table[] =
|
||||||
return false; \
|
return false; \
|
||||||
BLOCK_END
|
BLOCK_END
|
||||||
|
|
||||||
static void user_unref (void *p);
|
struct user;
|
||||||
static void channel_unref (void *p);
|
static void user_unref (struct user *self);
|
||||||
|
|
||||||
|
struct channel;
|
||||||
|
static void channel_unref (struct channel *self);
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
|
// We need a few reference countable objects with support
|
||||||
|
// for both strong and weak references
|
||||||
|
|
||||||
/// Callback just before a reference counted object is destroyed
|
/// Callback just before a reference counted object is destroyed
|
||||||
typedef void (*destroy_cb_fn) (void *object, void *user_data);
|
typedef void (*destroy_cb_fn) (void *object, void *user_data);
|
||||||
|
|
||||||
|
#define REF_COUNTABLE_HEADER \
|
||||||
|
size_t ref_count; /**< Reference count */ \
|
||||||
|
destroy_cb_fn on_destroy; /**< To remove any weak references */ \
|
||||||
|
void *user_data; /**< User data for callbacks */
|
||||||
|
|
||||||
|
#define REF_COUNTABLE_METHODS(name) \
|
||||||
|
static struct name * \
|
||||||
|
name ## _ref (struct name *self) \
|
||||||
|
{ \
|
||||||
|
self->ref_count++; \
|
||||||
|
return self; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
static void \
|
||||||
|
name ## _unref (struct name *self) \
|
||||||
|
{ \
|
||||||
|
if (--self->ref_count) \
|
||||||
|
return; \
|
||||||
|
if (self->on_destroy) \
|
||||||
|
self->on_destroy (self, self->user_data); \
|
||||||
|
name ## _destroy (self); \
|
||||||
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
struct user_channel
|
struct user_channel
|
||||||
|
@ -123,9 +154,8 @@ user_channel_new (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
user_channel_destroy (void *p)
|
user_channel_destroy (struct user_channel *self)
|
||||||
{
|
{
|
||||||
struct user_channel *self = p;
|
|
||||||
channel_unref (self->channel);
|
channel_unref (self->channel);
|
||||||
free (self);
|
free (self);
|
||||||
}
|
}
|
||||||
|
@ -137,10 +167,7 @@ user_channel_destroy (void *p)
|
||||||
|
|
||||||
struct user
|
struct user
|
||||||
{
|
{
|
||||||
size_t ref_count; ///< Reference count
|
REF_COUNTABLE_HEADER
|
||||||
|
|
||||||
destroy_cb_fn on_destroy; ///< To remove any weak references
|
|
||||||
void *user_data; ///< User data for callbacks
|
|
||||||
|
|
||||||
// TODO: eventually a reference to the server
|
// TODO: eventually a reference to the server
|
||||||
|
|
||||||
|
@ -162,29 +189,13 @@ user_new (void)
|
||||||
static void
|
static void
|
||||||
user_destroy (struct user *self)
|
user_destroy (struct user *self)
|
||||||
{
|
{
|
||||||
if (self->on_destroy)
|
|
||||||
self->on_destroy (self, self->user_data);
|
|
||||||
|
|
||||||
free (self->nickname);
|
free (self->nickname);
|
||||||
LIST_FOR_EACH (struct user_channel, iter, self->channels)
|
LIST_FOR_EACH (struct user_channel, iter, self->channels)
|
||||||
user_channel_destroy (iter);
|
user_channel_destroy (iter);
|
||||||
free (self);
|
free (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct user *
|
REF_COUNTABLE_METHODS (user)
|
||||||
user_ref (struct user *self)
|
|
||||||
{
|
|
||||||
self->ref_count++;
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
user_unref (void *p)
|
|
||||||
{
|
|
||||||
struct user *self = p;
|
|
||||||
if (!--self->ref_count)
|
|
||||||
user_destroy (self);
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
|
@ -204,9 +215,8 @@ channel_user_new (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
channel_user_destroy (void *p)
|
channel_user_destroy (struct channel_user *self)
|
||||||
{
|
{
|
||||||
struct channel_user *self = p;
|
|
||||||
user_unref (self->user);
|
user_unref (self->user);
|
||||||
free (self->modes);
|
free (self->modes);
|
||||||
free (self);
|
free (self);
|
||||||
|
@ -219,10 +229,7 @@ channel_user_destroy (void *p)
|
||||||
|
|
||||||
struct channel
|
struct channel
|
||||||
{
|
{
|
||||||
size_t ref_count; ///< Reference count
|
REF_COUNTABLE_HEADER
|
||||||
|
|
||||||
destroy_cb_fn on_destroy; ///< To remove any weak references
|
|
||||||
void *user_data; ///< User data for callbacks
|
|
||||||
|
|
||||||
// TODO: eventually a reference to the server
|
// TODO: eventually a reference to the server
|
||||||
|
|
||||||
|
@ -244,9 +251,6 @@ channel_new (void)
|
||||||
static void
|
static void
|
||||||
channel_destroy (struct channel *self)
|
channel_destroy (struct channel *self)
|
||||||
{
|
{
|
||||||
if (self->on_destroy)
|
|
||||||
self->on_destroy (self, self->user_data);
|
|
||||||
|
|
||||||
free (self->name);
|
free (self->name);
|
||||||
free (self->mode);
|
free (self->mode);
|
||||||
free (self->topic);
|
free (self->topic);
|
||||||
|
@ -255,20 +259,7 @@ channel_destroy (struct channel *self)
|
||||||
free (self);
|
free (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct channel *
|
REF_COUNTABLE_METHODS (channel)
|
||||||
channel_ref (struct channel *self)
|
|
||||||
{
|
|
||||||
self->ref_count++;
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
channel_unref (void *p)
|
|
||||||
{
|
|
||||||
struct channel *self = p;
|
|
||||||
if (!--self->ref_count)
|
|
||||||
channel_destroy (self);
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue