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
|
||||
// for both strong and weak references
|
||||
// We need a few reference countable objects with support for both strong
|
||||
// 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
|
||||
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 \
|
||||
size_t ref_count; /**< Reference count */ \
|
||||
destroy_cb_fn on_destroy; /**< To remove any weak references */ \
|
||||
void *user_data; /**< User data for callbacks */
|
||||
struct weak_ref_link *weak_refs; /**< To remove any weak references */
|
||||
|
||||
#define REF_COUNTABLE_METHODS(name) \
|
||||
static struct name * \
|
||||
@ -756,9 +769,31 @@ typedef void (*destroy_cb_fn) (void *object, void *user_data);
|
||||
{ \
|
||||
if (--self->ref_count) \
|
||||
return; \
|
||||
if (self->on_destroy) \
|
||||
self->on_destroy (self, self->user_data); \
|
||||
LIST_FOR_EACH (struct weak_ref_link, iter, self->weak_refs) \
|
||||
{ \
|
||||
iter->on_destroy (self, iter->user_data); \
|
||||
free (iter); \
|
||||
} \
|
||||
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));
|
||||
|
||||
struct user *user = user_new ();
|
||||
user->on_destroy = irc_user_on_destroy;
|
||||
user->user_data = s;
|
||||
(void) user_weak_ref (user, irc_user_on_destroy, s);
|
||||
user->nickname = nickname;
|
||||
str_map_set (&s->irc_users, user->nickname, user);
|
||||
return user;
|
||||
@ -3482,8 +3516,7 @@ irc_make_channel (struct server *s, char *name)
|
||||
hard_assert (!str_map_find (&s->irc_channels, name));
|
||||
|
||||
struct channel *channel = channel_new ();
|
||||
channel->on_destroy = irc_channel_on_destroy;
|
||||
channel->user_data = s;
|
||||
(void) channel_weak_ref (channel, irc_channel_on_destroy, s);
|
||||
channel->name = name;
|
||||
channel->topic = NULL;
|
||||
str_map_set (&s->irc_channels, channel->name, channel);
|
||||
|
Loading…
Reference in New Issue
Block a user