diff options
author | Wilmer van der Gaast <wilmer@gaast.net> | 2010-06-28 10:03:39 +0100 |
---|---|---|
committer | Wilmer van der Gaast <wilmer@gaast.net> | 2010-06-28 10:03:39 +0100 |
commit | ab6006cfec72ae8669c68f2892cf1c9994740c92 (patch) | |
tree | ba393d5e2badd7a64fc2d521fe5a415f6798ed13 /irc_channel.c | |
parent | c7eb7719b4642b72669d280d4c24c54109ed0d28 (diff) |
Callers shouldn't have to expect that irc_channel_del_user() frees the channel
so if it wants to (temporary channels), do it via a timer.
Diffstat (limited to 'irc_channel.c')
-rw-r--r-- | irc_channel.c | 36 |
1 files changed, 35 insertions, 1 deletions
diff --git a/irc_channel.c b/irc_channel.c index 534f49c4..fc89ddd3 100644 --- a/irc_channel.c +++ b/irc_channel.c @@ -140,6 +140,40 @@ int irc_channel_free( irc_channel_t *ic ) return 1; } +struct irc_channel_free_data +{ + irc_t *irc; + irc_channel_t *ic; + char *name; +}; + +static gboolean irc_channel_free_callback( gpointer data, gint fd, b_input_condition cond ) +{ + struct irc_channel_free_data *d = data; + + if( g_slist_find( irc_connection_list, d->irc ) && + irc_channel_by_name( d->irc, d->name ) == d->ic && + !( d->ic->flags & IRC_CHANNEL_JOINED ) ) + irc_channel_free( d->ic ); + + g_free( d->name ); + g_free( d ); + return FALSE; +} + +/* Free the channel, but via the event loop, so after finishing whatever event + we're currently handling. */ +void irc_channel_free_soon( irc_channel_t *ic ) +{ + struct irc_channel_free_data *d = g_new0( struct irc_channel_free_data, 1 ); + + d->irc = ic->irc; + d->ic = ic; + d->name = g_strdup( ic->name ); + + b_timeout_add( 0, irc_channel_free_callback, d ); +} + static char *set_eval_channel_type( set_t *set, char *value ) { struct irc_channel *ic = set->data; @@ -205,7 +239,7 @@ int irc_channel_del_user( irc_channel_t *ic, irc_user_t *iu, gboolean silent, co ic->flags &= ~IRC_CHANNEL_JOINED; if( ic->flags & IRC_CHANNEL_TEMP ) - irc_channel_free( ic ); + irc_channel_free_soon( ic ); } return 1; |