[vim] 108/139: patch 7.4.1791 Problem: Channel could be garbage collected too early. Solution: Don't free a channel or remove it from a job when it is still useful.

James McCoy jamessan at debian.org
Fri May 6 04:00:12 UTC 2016


This is an automated email from the git hooks/post-receive script.

jamessan pushed a commit to branch debian/sid
in repository vim.

commit 674127e1801fd02ff07dddf0dc3bf0d8cce68997
Author: Bram Moolenaar <Bram at vim.org>
Date:   Tue Apr 26 20:30:07 2016 +0200

    patch 7.4.1791
    Problem:    Channel could be garbage collected too early.
    Solution:   Don't free a channel or remove it from a job when it is still
                useful.
---
 src/channel.c | 17 ++++++++++++-----
 src/version.c |  2 ++
 2 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/src/channel.c b/src/channel.c
index 1ebb675..1be3d27 100644
--- a/src/channel.c
+++ b/src/channel.c
@@ -439,7 +439,8 @@ free_unused_channels_contents(int copyID, int mask)
     channel_T	*ch;
 
     for (ch = first_channel; ch != NULL; ch = ch->ch_next)
-	if ((ch->ch_copyID & mask) != (copyID & mask))
+	if (!channel_still_useful(ch)
+				 && (ch->ch_copyID & mask) != (copyID & mask))
 	{
 	    /* Free the channel and ordinary items it contains, but don't
 	     * recurse into Lists, Dictionaries etc. */
@@ -458,7 +459,8 @@ free_unused_channels(int copyID, int mask)
     for (ch = first_channel; ch != NULL; ch = ch_next)
     {
 	ch_next = ch->ch_next;
-	if ((ch->ch_copyID & mask) != (copyID & mask))
+	if (!channel_still_useful(ch)
+				 && (ch->ch_copyID & mask) != (copyID & mask))
 	{
 	    /* Free the channel struct itself. */
 	    channel_free_channel(ch);
@@ -4079,13 +4081,16 @@ job_free(job_T *job)
 
 /*
  * Return TRUE if the job should not be freed yet.  Do not free the job when
- * it has not ended yet and there is a "stoponexit" flag or an exit callback.
+ * it has not ended yet and there is a "stoponexit" flag, an exit callback
+ * or when the associated channel will do something with the job output.
  */
     static int
 job_still_useful(job_T *job)
 {
     return job->jv_status == JOB_STARTED
-		   && (job->jv_stoponexit != NULL || job->jv_exit_cb != NULL);
+	       && (job->jv_stoponexit != NULL || job->jv_exit_cb != NULL
+		   || (job->jv_channel != NULL
+		       && channel_still_useful(job->jv_channel)));
 }
 
     void
@@ -4099,10 +4104,12 @@ job_unref(job_T *job)
 	{
 	    job_free(job);
 	}
-	else if (job->jv_channel != NULL)
+	else if (job->jv_channel != NULL
+				    && !channel_still_useful(job->jv_channel))
 	{
 	    /* Do remove the link to the channel, otherwise it hangs
 	     * around until Vim exits. See job_free() for refcount. */
+	    ch_log(job->jv_channel, "detaching channel from job");
 	    job->jv_channel->ch_job = NULL;
 	    channel_unref(job->jv_channel);
 	    job->jv_channel = NULL;
diff --git a/src/version.c b/src/version.c
index cd760ab..a2553e6 100644
--- a/src/version.c
+++ b/src/version.c
@@ -754,6 +754,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    1791,
+/**/
     1790,
 /**/
     1789,

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-vim/vim.git



More information about the pkg-vim-maintainers mailing list