Mercurial > vim
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 |