degesch: extend weak pointers
This commit is contained in:
parent
89065e4d34
commit
b952fc1f6d
53
degesch.c
53
degesch.c
|
@ -732,16 +732,29 @@ input_on_readable (struct input *self)
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
// We need a few reference countable objects with support
|
// We need a few reference countable objects with support for both strong
|
||||||
// for both strong and weak references
|
// and weak references (mainly used for scripted plugins).
|
||||||
|
//
|
||||||
|
// Beware that if you don't own the object, you will most probably want
|
||||||
|
// to keep the weak reference link so that you can get rid of it later.
|
||||||
|
// Also note that you have to make sure the user_data don't leak resources.
|
||||||
|
//
|
||||||
|
// Having a callback is more versatile than just nulling out a pointer.
|
||||||
|
|
||||||
/// 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);
|
||||||
|
|
||||||
|
struct weak_ref_link
|
||||||
|
{
|
||||||
|
LIST_HEADER (struct weak_ref_link)
|
||||||
|
|
||||||
|
destroy_cb_fn on_destroy; ///< Called when object is destroyed
|
||||||
|
void *user_data; ///< User data
|
||||||
|
};
|
||||||
|
|
||||||
#define REF_COUNTABLE_HEADER \
|
#define REF_COUNTABLE_HEADER \
|
||||||
size_t ref_count; /**< Reference count */ \
|
size_t ref_count; /**< Reference count */ \
|
||||||
destroy_cb_fn on_destroy; /**< To remove any weak references */ \
|
struct weak_ref_link *weak_refs; /**< To remove any weak references */
|
||||||
void *user_data; /**< User data for callbacks */
|
|
||||||
|
|
||||||
#define REF_COUNTABLE_METHODS(name) \
|
#define REF_COUNTABLE_METHODS(name) \
|
||||||
static struct name * \
|
static struct name * \
|
||||||
|
@ -756,9 +769,31 @@ typedef void (*destroy_cb_fn) (void *object, void *user_data);
|
||||||
{ \
|
{ \
|
||||||
if (--self->ref_count) \
|
if (--self->ref_count) \
|
||||||
return; \
|
return; \
|
||||||
if (self->on_destroy) \
|
LIST_FOR_EACH (struct weak_ref_link, iter, self->weak_refs) \
|
||||||
self->on_destroy (self, self->user_data); \
|
{ \
|
||||||
|
iter->on_destroy (self, iter->user_data); \
|
||||||
|
free (iter); \
|
||||||
|
} \
|
||||||
name ## _destroy (self); \
|
name ## _destroy (self); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
static struct weak_ref_link * \
|
||||||
|
name ## _weak_ref (struct name *self, destroy_cb_fn cb, void *user_data) \
|
||||||
|
{ \
|
||||||
|
struct weak_ref_link *link = xcalloc (1, sizeof *link); \
|
||||||
|
link->on_destroy = cb; \
|
||||||
|
link->user_data = user_data; \
|
||||||
|
LIST_PREPEND (self->weak_refs, link); \
|
||||||
|
return link; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
static void \
|
||||||
|
name ## _weak_unref (struct name *self, struct weak_ref_link **link) \
|
||||||
|
{ \
|
||||||
|
if (*link) \
|
||||||
|
LIST_UNLINK (self->weak_refs, *link); \
|
||||||
|
free (*link); \
|
||||||
|
*link = NULL; \
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -3378,8 +3413,7 @@ irc_make_user (struct server *s, char *nickname)
|
||||||
hard_assert (!str_map_find (&s->irc_users, nickname));
|
hard_assert (!str_map_find (&s->irc_users, nickname));
|
||||||
|
|
||||||
struct user *user = user_new ();
|
struct user *user = user_new ();
|
||||||
user->on_destroy = irc_user_on_destroy;
|
(void) user_weak_ref (user, irc_user_on_destroy, s);
|
||||||
user->user_data = s;
|
|
||||||
user->nickname = nickname;
|
user->nickname = nickname;
|
||||||
str_map_set (&s->irc_users, user->nickname, user);
|
str_map_set (&s->irc_users, user->nickname, user);
|
||||||
return user;
|
return user;
|
||||||
|
@ -3482,8 +3516,7 @@ irc_make_channel (struct server *s, char *name)
|
||||||
hard_assert (!str_map_find (&s->irc_channels, name));
|
hard_assert (!str_map_find (&s->irc_channels, name));
|
||||||
|
|
||||||
struct channel *channel = channel_new ();
|
struct channel *channel = channel_new ();
|
||||||
channel->on_destroy = irc_channel_on_destroy;
|
(void) channel_weak_ref (channel, irc_channel_on_destroy, s);
|
||||||
channel->user_data = s;
|
|
||||||
channel->name = name;
|
channel->name = name;
|
||||||
channel->topic = NULL;
|
channel->topic = NULL;
|
||||||
str_map_set (&s->irc_channels, channel->name, channel);
|
str_map_set (&s->irc_channels, channel->name, channel);
|
||||||
|
|
Loading…
Reference in New Issue