Skip to content

Commit 674127e

Browse files
committed
patch 7.4.1791
Problem: Channel could be garbage collected too early. Solution: Don't free a channel or remove it from a job when it is still useful.
1 parent 6231cb8 commit 674127e

2 files changed

Lines changed: 14 additions & 5 deletions

File tree

src/channel.c

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,8 @@ free_unused_channels_contents(int copyID, int mask)
439439
channel_T *ch;
440440

441441
for (ch = first_channel; ch != NULL; ch = ch->ch_next)
442-
if ((ch->ch_copyID & mask) != (copyID & mask))
442+
if (!channel_still_useful(ch)
443+
&& (ch->ch_copyID & mask) != (copyID & mask))
443444
{
444445
/* Free the channel and ordinary items it contains, but don't
445446
* recurse into Lists, Dictionaries etc. */
@@ -458,7 +459,8 @@ free_unused_channels(int copyID, int mask)
458459
for (ch = first_channel; ch != NULL; ch = ch_next)
459460
{
460461
ch_next = ch->ch_next;
461-
if ((ch->ch_copyID & mask) != (copyID & mask))
462+
if (!channel_still_useful(ch)
463+
&& (ch->ch_copyID & mask) != (copyID & mask))
462464
{
463465
/* Free the channel struct itself. */
464466
channel_free_channel(ch);
@@ -4079,13 +4081,16 @@ job_free(job_T *job)
40794081

40804082
/*
40814083
* Return TRUE if the job should not be freed yet. Do not free the job when
4082-
* it has not ended yet and there is a "stoponexit" flag or an exit callback.
4084+
* it has not ended yet and there is a "stoponexit" flag, an exit callback
4085+
* or when the associated channel will do something with the job output.
40834086
*/
40844087
static int
40854088
job_still_useful(job_T *job)
40864089
{
40874090
return job->jv_status == JOB_STARTED
4088-
&& (job->jv_stoponexit != NULL || job->jv_exit_cb != NULL);
4091+
&& (job->jv_stoponexit != NULL || job->jv_exit_cb != NULL
4092+
|| (job->jv_channel != NULL
4093+
&& channel_still_useful(job->jv_channel)));
40894094
}
40904095

40914096
void
@@ -4099,10 +4104,12 @@ job_unref(job_T *job)
40994104
{
41004105
job_free(job);
41014106
}
4102-
else if (job->jv_channel != NULL)
4107+
else if (job->jv_channel != NULL
4108+
&& !channel_still_useful(job->jv_channel))
41034109
{
41044110
/* Do remove the link to the channel, otherwise it hangs
41054111
* around until Vim exits. See job_free() for refcount. */
4112+
ch_log(job->jv_channel, "detaching channel from job");
41064113
job->jv_channel->ch_job = NULL;
41074114
channel_unref(job->jv_channel);
41084115
job->jv_channel = NULL;

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -753,6 +753,8 @@ static char *(features[]) =
753753

754754
static int included_patches[] =
755755
{ /* Add new patch number below this line */
756+
/**/
757+
1791,
756758
/**/
757759
1790,
758760
/**/

0 commit comments

Comments
 (0)