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.
diff --git a/src/channel.c b/src/channel.c
index 83d057d..72484ec 100644
--- a/src/channel.c
+++ b/src/channel.c
@@ -458,8 +458,7 @@
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 @@
}
}
+/*
+ * 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 @@
{
/* 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 @@
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 @@
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);
}
}