comparison 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
comparison
equal deleted inserted replaced
8880:9f57791bc922 8881:ed0b39dd7fd6
456 for (ch = first_channel; ch != NULL; ch = ch_next) 456 for (ch = first_channel; ch != NULL; ch = ch_next)
457 { 457 {
458 ch_next = ch->ch_next; 458 ch_next = ch->ch_next;
459 if ((ch->ch_copyID & mask) != (copyID & mask)) 459 if ((ch->ch_copyID & mask) != (copyID & mask))
460 { 460 {
461 /* Free the channel and ordinary items it contains, but don't 461 /* Free the channel struct itself. */
462 * recurse into Lists, Dictionaries etc. */
463 channel_free_channel(ch); 462 channel_free_channel(ch);
464 } 463 }
465 } 464 }
466 } 465 }
467 466
4004 job_free_contents(job); 4003 job_free_contents(job);
4005 job_free_job(job); 4004 job_free_job(job);
4006 } 4005 }
4007 } 4006 }
4008 4007
4008 /*
4009 * Return TRUE if the job should not be freed yet. Do not free the job when
4010 * it has not ended yet and there is a "stoponexit" flag or an exit callback.
4011 */
4012 static int
4013 job_still_useful(job_T *job)
4014 {
4015 return job->jv_status == JOB_STARTED
4016 && (job->jv_stoponexit != NULL || job->jv_exit_cb != NULL);
4017 }
4018
4009 void 4019 void
4010 job_unref(job_T *job) 4020 job_unref(job_T *job)
4011 { 4021 {
4012 if (job != NULL && --job->jv_refcount <= 0) 4022 if (job != NULL && --job->jv_refcount <= 0)
4013 { 4023 {
4014 /* Do not free the job when it has not ended yet and there is a 4024 /* Do not free the job when it has not ended yet and there is a
4015 * "stoponexit" flag or an exit callback. */ 4025 * "stoponexit" flag or an exit callback. */
4016 if (job->jv_status != JOB_STARTED 4026 if (!job_still_useful(job))
4017 || (job->jv_stoponexit == NULL && job->jv_exit_cb == NULL))
4018 { 4027 {
4019 job_free(job); 4028 job_free(job);
4020 } 4029 }
4021 else if (job->jv_channel != NULL) 4030 else if (job->jv_channel != NULL)
4022 { 4031 {
4034 { 4043 {
4035 int did_free = FALSE; 4044 int did_free = FALSE;
4036 job_T *job; 4045 job_T *job;
4037 4046
4038 for (job = first_job; job != NULL; job = job->jv_next) 4047 for (job = first_job; job != NULL; job = job->jv_next)
4039 if ((job->jv_copyID & mask) != (copyID & mask)) 4048 if ((job->jv_copyID & mask) != (copyID & mask)
4049 && !job_still_useful(job))
4040 { 4050 {
4041 /* Free the channel and ordinary items it contains, but don't 4051 /* Free the channel and ordinary items it contains, but don't
4042 * recurse into Lists, Dictionaries etc. */ 4052 * recurse into Lists, Dictionaries etc. */
4043 job_free_contents(job); 4053 job_free_contents(job);
4044 did_free = TRUE; 4054 did_free = TRUE;
4053 job_T *job_next; 4063 job_T *job_next;
4054 4064
4055 for (job = first_job; job != NULL; job = job_next) 4065 for (job = first_job; job != NULL; job = job_next)
4056 { 4066 {
4057 job_next = job->jv_next; 4067 job_next = job->jv_next;
4058 if ((job->jv_copyID & mask) != (copyID & mask)) 4068 if ((job->jv_copyID & mask) != (copyID & mask)
4059 { 4069 && !job_still_useful(job))
4060 /* Free the channel and ordinary items it contains, but don't 4070 {
4061 * recurse into Lists, Dictionaries etc. */ 4071 /* Free the job struct itself. */
4062 job_free_job(job); 4072 job_free_job(job);
4063 } 4073 }
4064 } 4074 }
4065 } 4075 }
4066 4076