degesch: memory management fixes

As well as a one serious bug in passing the completely wrong object.
This commit is contained in:
Přemysl Eric Janouch 2015-04-24 23:30:48 +02:00
parent a4d3023874
commit 7c2085d528
1 changed files with 18 additions and 11 deletions

View File

@ -144,6 +144,8 @@ struct user_channel
{ {
LIST_HEADER (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 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_mode);
free (self->irc_user_host); 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_users);
str_map_free (&self->irc_channels); str_map_free (&self->irc_channels);
str_map_free (&self->irc_buffer_map); str_map_free (&self->irc_buffer_map);
poller_free (&self->poller); 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->latin1_to_utf8);
iconv_close (self->term_from_utf8); iconv_close (self->term_from_utf8);
iconv_close (self->term_to_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_STATE *state = history_get_history_state ();
history_set_history_state (buffer->history); history_set_history_state (buffer->history);
free (buffer->history);
rl_clear_history (); rl_clear_history ();
history_set_history_state (state); 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); struct user *user = str_map_find (&ctx->irc_users, nickname);
if (!user) if (!user)
user = irc_make_user (ctx, xstrdup (nickname)); user = irc_make_user (ctx, xstrdup (nickname));
else
user = user_ref (user);
// Open a new buffer for the user // Open a new buffer for the user
buffer = buffer_new (); buffer = buffer_new ();
buffer->type = BUFFER_PM; buffer->type = BUFFER_PM;
buffer->name = xstrdup (nickname); buffer->name = xstrdup (nickname);
buffer->user = user_ref (user); buffer->user = user;
LIST_APPEND_WITH_TAIL (ctx->buffers, ctx->buffers_tail, buffer); LIST_APPEND_WITH_TAIL (ctx->buffers, ctx->buffers_tail, buffer);
str_map_set (&ctx->irc_buffer_map, user->nickname, buffer); str_map_set (&ctx->irc_buffer_map, user->nickname, buffer);
return 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 // We've joined a new channel
if (!channel && irc_is_this_us (ctx, msg->prefix)) if (!channel && irc_is_this_us (ctx, msg->prefix))
{ {
channel = irc_make_channel (ctx, xstrdup (channel_name));
buffer = buffer_new (); buffer = buffer_new ();
buffer->type = BUFFER_CHANNEL; buffer->type = BUFFER_CHANNEL;
buffer->name = xstrdup (channel_name); 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); LIST_APPEND_WITH_TAIL (ctx->buffers, ctx->buffers_tail, buffer);
str_map_set (&ctx->irc_buffer_map, channel->name, 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) if (!user)
user = irc_make_user (ctx, nickname); user = irc_make_user (ctx, nickname);
else else
{
user = user_ref (user);
free (nickname); free (nickname);
}
// Link the user with the channel // Link the user with the channel
struct user_channel *user_channel = user_channel_new (); 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); LIST_PREPEND (user->channels, user_channel);
struct channel_user *channel_user = channel_user_new (); struct channel_user *channel_user = channel_user_new ();
channel_user->user = user_ref (user); channel_user->user = user;
channel_user->modes = xstrdup (""); channel_user->modes = xstrdup ("");
LIST_PREPEND (channel->users, channel_user); 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); str_map_find (&ctx->irc_buffer_map, user->nickname);
if (pm_buffer) 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); str_map_set (&ctx->irc_buffer_map, user->nickname, NULL);
buffer_send (ctx, pm_buffer, BUFFER_LINE_NICK, 0, 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_fd = -1;
ctx->irc_ready = false; ctx->irc_ready = false;
str_map_set (&ctx->irc_users, ctx->irc_user->nickname, NULL);
user_unref (ctx->irc_user); user_unref (ctx->irc_user);
ctx->irc_user = NULL; ctx->irc_user = NULL;