summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2017-09-09 16:42:53 +0200
committerBram Moolenaar <Bram@vim.org>2017-09-09 16:42:53 +0200
commitaba680a8513124e9556956115db4df35bd4a0e56 (patch)
tree3e4417baac7c2a36163abfabc866e70c2224b589
parent74121231be50e245d18c64281fdef08e7ec1ed5b (diff)
patch 8.0.1081: memory leak for the channel write queuev8.0.1081
Problem: Memory leak for the channel write queue. Solution: Free the write queue when clearing a channel.
-rw-r--r--src/channel.c34
-rw-r--r--src/version.c2
2 files changed, 24 insertions, 12 deletions
diff --git a/src/channel.c b/src/channel.c
index dfb8ac989f..0e9a58007e 100644
--- a/src/channel.c
+++ b/src/channel.c
@@ -2930,14 +2930,26 @@ channel_close_in(channel_T *channel)
ch_close_part(channel, PART_IN);
}
+ static void
+remove_from_writeque(writeq_T *wq, writeq_T *entry)
+{
+ ga_clear(&entry->wq_ga);
+ wq->wq_next = entry->wq_next;
+ if (wq->wq_next == NULL)
+ wq->wq_prev = NULL;
+ else
+ wq->wq_next->wq_prev = NULL;
+}
+
/*
* Clear the read buffer on "channel"/"part".
*/
static void
channel_clear_one(channel_T *channel, ch_part_T part)
{
- jsonq_T *json_head = &channel->ch_part[part].ch_json_head;
- cbq_T *cb_head = &channel->ch_part[part].ch_cb_head;
+ chanpart_T *ch_part = &channel->ch_part[part];
+ jsonq_T *json_head = &ch_part->ch_json_head;
+ cbq_T *cb_head = &ch_part->ch_cb_head;
while (channel_peek(channel, part) != NULL)
vim_free(channel_get(channel, part));
@@ -2957,10 +2969,13 @@ channel_clear_one(channel_T *channel, ch_part_T part)
remove_json_node(json_head, json_head->jq_next);
}
- free_callback(channel->ch_part[part].ch_callback,
- channel->ch_part[part].ch_partial);
- channel->ch_part[part].ch_callback = NULL;
- channel->ch_part[part].ch_partial = NULL;
+ free_callback(ch_part->ch_callback, ch_part->ch_partial);
+ ch_part->ch_callback = NULL;
+ ch_part->ch_partial = NULL;
+
+ while (ch_part->ch_writeque.wq_next != NULL)
+ remove_from_writeque(&ch_part->ch_writeque,
+ ch_part->ch_writeque.wq_next);
}
/*
@@ -3719,12 +3734,7 @@ channel_send(
if (entry != NULL)
{
/* Remove the entry from the write queue. */
- ga_clear(&entry->wq_ga);
- wq->wq_next = entry->wq_next;
- if (wq->wq_next == NULL)
- wq->wq_prev = NULL;
- else
- wq->wq_next->wq_prev = NULL;
+ remove_from_writeque(wq, entry);
continue;
}
if (did_use_queue)
diff --git a/src/version.c b/src/version.c
index 989fe04275..0018bce758 100644
--- a/src/version.c
+++ b/src/version.c
@@ -770,6 +770,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1081,
+/**/
1080,
/**/
1079,