From 7c2085d528395420d1d1d9b300e358abc5b08a52 Mon Sep 17 00:00:00 2001
From: Přemysl Janouch
Date: Fri, 24 Apr 2015 23:30:48 +0200
Subject: degesch: memory management fixes
As well as a one serious bug in passing the completely wrong object.
---
degesch.c | 29 ++++++++++++++++++-----------
1 file changed, 18 insertions(+), 11 deletions(-)
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;
--
cgit v1.2.3-70-g09d2