]> granicus.if.org Git - vim/commitdiff
patch 8.0.1081: memory leak for the channel write queue v8.0.1081
authorBram Moolenaar <Bram@vim.org>
Sat, 9 Sep 2017 14:42:53 +0000 (16:42 +0200)
committerBram Moolenaar <Bram@vim.org>
Sat, 9 Sep 2017 14:42:53 +0000 (16:42 +0200)
Problem:    Memory leak for the channel write queue.
Solution:   Free the write queue when clearing a channel.

src/channel.c
src/version.c

index dfb8ac989f1e9b5acc70d134d3175d775a95bea3..0e9a58007e37dafc57cde77fe268d2a3ed46dc23 100644 (file)
@@ -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)
index 989fe042752b2e51220ce4eb962648d911ad4595..0018bce75815d5f6422da5b8666903c34e11bb46 100644 (file)
@@ -769,6 +769,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1081,
 /**/
     1080,
 /**/