diff --git a/degesch.c b/degesch.c index f2d5b4e..12850ed 100644 --- a/degesch.c +++ b/degesch.c @@ -144,6 +144,8 @@ struct user_channel { LIST_HEADER (struct user_channel) + // FIXME: this should be a weak reference to destroy a cycle + struct channel *channel; ///< Reference to channel }; @@ -541,16 +543,17 @@ app_context_free (struct app_context *self) free (self->irc_user_mode); free (self->irc_user_host); + // FIXME: this doesn't free the history state + LIST_FOR_EACH (struct buffer, iter, self->buffers) + buffer_destroy (iter); + str_map_free (&self->buffers_by_name); + str_map_free (&self->irc_users); str_map_free (&self->irc_channels); str_map_free (&self->irc_buffer_map); poller_free (&self->poller); - LIST_FOR_EACH (struct buffer, iter, self->buffers) - buffer_destroy (iter); - str_map_free (&self->buffers_by_name); - iconv_close (self->latin1_to_utf8); iconv_close (self->term_from_utf8); iconv_close (self->term_to_utf8); @@ -1051,6 +1054,7 @@ buffer_remove (struct app_context *ctx, struct buffer *buffer) HISTORY_STATE *state = history_get_history_state (); history_set_history_state (buffer->history); + free (buffer->history); rl_clear_history (); history_set_history_state (state); @@ -1310,12 +1314,14 @@ irc_get_or_make_user_buffer (struct app_context *ctx, const char *nickname) struct user *user = str_map_find (&ctx->irc_users, nickname); if (!user) user = irc_make_user (ctx, xstrdup (nickname)); + else + user = user_ref (user); // Open a new buffer for the user buffer = buffer_new (); buffer->type = BUFFER_PM; buffer->name = xstrdup (nickname); - buffer->user = user_ref (user); + buffer->user = user; LIST_APPEND_WITH_TAIL (ctx->buffers, ctx->buffers_tail, buffer); str_map_set (&ctx->irc_buffer_map, user->nickname, buffer); return buffer; @@ -1911,12 +1917,11 @@ irc_handle_join (struct app_context *ctx, const struct irc_message *msg) // We've joined a new channel if (!channel && irc_is_this_us (ctx, msg->prefix)) { - channel = irc_make_channel (ctx, xstrdup (channel_name)); - buffer = buffer_new (); buffer->type = BUFFER_CHANNEL; buffer->name = xstrdup (channel_name); - buffer->channel = channel_ref (channel); + buffer->channel = channel = + irc_make_channel (ctx, xstrdup (channel_name)); LIST_APPEND_WITH_TAIL (ctx->buffers, ctx->buffers_tail, buffer); str_map_set (&ctx->irc_buffer_map, channel->name, buffer); @@ -1933,7 +1938,10 @@ irc_handle_join (struct app_context *ctx, const struct irc_message *msg) if (!user) user = irc_make_user (ctx, nickname); else + { + user = user_ref (user); free (nickname); + } // Link the user with the channel struct user_channel *user_channel = user_channel_new (); @@ -1941,7 +1949,7 @@ irc_handle_join (struct app_context *ctx, const struct irc_message *msg) LIST_PREPEND (user->channels, user_channel); struct channel_user *channel_user = channel_user_new (); - channel_user->user = user_ref (user); + channel_user->user = user; channel_user->modes = xstrdup (""); LIST_PREPEND (channel->users, channel_user); @@ -2018,7 +2026,7 @@ irc_handle_nick (struct app_context *ctx, const struct irc_message *msg) str_map_find (&ctx->irc_buffer_map, user->nickname); if (pm_buffer) { - str_map_set (&ctx->irc_buffer_map, new_nickname, user_ref (user)); + str_map_set (&ctx->irc_buffer_map, new_nickname, pm_buffer); str_map_set (&ctx->irc_buffer_map, user->nickname, NULL); buffer_send (ctx, pm_buffer, BUFFER_LINE_NICK, 0, @@ -3143,7 +3151,6 @@ on_irc_disconnected (struct app_context *ctx) ctx->irc_fd = -1; ctx->irc_ready = false; - str_map_set (&ctx->irc_users, ctx->irc_user->nickname, NULL); user_unref (ctx->irc_user); ctx->irc_user = NULL;