0
0
mirror of https://github.com/vim/vim.git synced 2025-10-04 05:25:06 -04:00

patch 8.1.0960: when using ConPTY garbage collection has undefined behavior

Problem:    When using ConPTY garbage collection has undefined behavior.
Solution:   Free the channel in a better way. (Nobuhiro Takasaki, closes #4020)
This commit is contained in:
Bram Moolenaar
2019-02-20 22:45:06 +01:00
parent a25e3d0695
commit 8caa43d815
2 changed files with 13 additions and 13 deletions

View File

@@ -191,7 +191,7 @@ ch_log_lead(const char *what, channel_T *ch, ch_part_T part)
static int did_log_msg = TRUE; static int did_log_msg = TRUE;
#ifndef PROTO /* prototype is in vim.h */ #ifndef PROTO // prototype is in proto.h
void void
ch_log(channel_T *ch, const char *fmt, ...) ch_log(channel_T *ch, const char *fmt, ...)
{ {
@@ -4348,20 +4348,25 @@ channel_parse_messages(void)
{ {
channel->ch_to_be_closed = (1U << PART_COUNT); channel->ch_to_be_closed = (1U << PART_COUNT);
channel_close_now(channel); channel_close_now(channel);
/* channel may have been freed, start over */ // channel may have been freed, start over
channel = first_channel; channel = first_channel;
continue; continue;
} }
if (channel->ch_to_be_freed || channel->ch_killing) if (channel->ch_to_be_freed || channel->ch_killing)
{ {
if (channel->ch_killing)
{
channel_free_contents(channel);
channel->ch_job->jv_channel = NULL;
}
channel_free(channel); channel_free(channel);
/* channel has been freed, start over */ // channel has been freed, start over
channel = first_channel; channel = first_channel;
continue; continue;
} }
if (channel->ch_refcount == 0 && !channel_still_useful(channel)) if (channel->ch_refcount == 0 && !channel_still_useful(channel))
{ {
/* channel is no longer useful, free it */ // channel is no longer useful, free it
channel_free(channel); channel_free(channel);
channel = first_channel; channel = first_channel;
part = PART_SOCK; part = PART_SOCK;
@@ -5487,15 +5492,8 @@ job_cleanup(job_T *job)
channel_need_redraw = TRUE; channel_need_redraw = TRUE;
} }
if (job->jv_channel != NULL if (job->jv_channel != NULL && job->jv_channel->ch_anonymous_pipe)
&& job->jv_channel->ch_anonymous_pipe && !job->jv_channel->ch_killing) job->jv_channel->ch_killing = TRUE;
{
++safe_to_invoke_callback;
channel_free_contents(job->jv_channel);
job->jv_channel->ch_job = NULL;
job->jv_channel = NULL;
--safe_to_invoke_callback;
}
// Do not free the job in case the close callback of the associated channel // Do not free the job in case the close callback of the associated channel
// isn't invoked yet and may get information by job_info(). // isn't invoked yet and may get information by job_info().

View File

@@ -779,6 +779,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
960,
/**/ /**/
959, 959,
/**/ /**/