diff options
author | Bram Moolenaar <Bram@vim.org> | 2017-09-09 16:42:53 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2017-09-09 16:42:53 +0200 |
commit | aba680a8513124e9556956115db4df35bd4a0e56 (patch) | |
tree | 3e4417baac7c2a36163abfabc866e70c2224b589 /src/channel.c | |
parent | 74121231be50e245d18c64281fdef08e7ec1ed5b (diff) | |
download | vim-git-aba680a8513124e9556956115db4df35bd4a0e56.tar.gz |
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.
Diffstat (limited to 'src/channel.c')
-rw-r--r-- | src/channel.c | 34 |
1 files changed, 22 insertions, 12 deletions
diff --git a/src/channel.c b/src/channel.c index dfb8ac989..0e9a58007 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) |