Mercurial > vim
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); } }