diff src/channel.c @ 8881:ed0b39dd7fd6 v7.4.1727

commit https://github.com/vim/vim/commit/ebf7dfa6f121c82f97d2adca3d45fbaba9ad8f7e Author: Bram Moolenaar <Bram@vim.org> Date: Thu Apr 14 12:46:51 2016 +0200 patch 7.4.1727 Problem: Cannot detect a crash in tests when caused by garbagecollect(). Solution: Add garbagecollect_for_testing(). Do not free a job if is still useful.
author Christian Brabandt <cb@256bit.org>
date Thu, 14 Apr 2016 13:00:06 +0200
parents e1b84109506a
children e6916e1683bb
line wrap: on
line diff
--- a/src/channel.c
+++ b/src/channel.c
@@ -458,8 +458,7 @@ free_unused_channels(int copyID, int mas
 	ch_next = ch->ch_next;
 	if ((ch->ch_copyID & mask) != (copyID & mask))
 	{
-	    /* Free the channel and ordinary items it contains, but don't
-	     * recurse into Lists, Dictionaries etc. */
+	    /* Free the channel struct itself. */
 	    channel_free_channel(ch);
 	}
     }
@@ -4006,6 +4005,17 @@ 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.
+ */
+    static int
+job_still_useful(job_T *job)
+{
+    return job->jv_status == JOB_STARTED
+		   && (job->jv_stoponexit != NULL || job->jv_exit_cb != NULL);
+}
+
     void
 job_unref(job_T *job)
 {
@@ -4013,8 +4023,7 @@ job_unref(job_T *job)
     {
 	/* Do not free the job when it has not ended yet and there is a
 	 * "stoponexit" flag or an exit callback. */
-	if (job->jv_status != JOB_STARTED
-		|| (job->jv_stoponexit == NULL && job->jv_exit_cb == NULL))
+	if (!job_still_useful(job))
 	{
 	    job_free(job);
 	}
@@ -4036,7 +4045,8 @@ free_unused_jobs_contents(int copyID, in
     job_T	*job;
 
     for (job = first_job; job != NULL; job = job->jv_next)
-	if ((job->jv_copyID & mask) != (copyID & mask))
+	if ((job->jv_copyID & mask) != (copyID & mask)
+						    && !job_still_useful(job))
 	{
 	    /* Free the channel and ordinary items it contains, but don't
 	     * recurse into Lists, Dictionaries etc. */
@@ -4055,10 +4065,10 @@ free_unused_jobs(int copyID, int mask)
     for (job = first_job; job != NULL; job = job_next)
     {
 	job_next = job->jv_next;
-	if ((job->jv_copyID & mask) != (copyID & mask))
+	if ((job->jv_copyID & mask) != (copyID & mask)
+						    && !job_still_useful(job))
 	{
-	    /* Free the channel and ordinary items it contains, but don't
-	     * recurse into Lists, Dictionaries etc. */
+	    /* Free the job struct itself. */
 	    job_free_job(job);
 	}
     }