forked from aniani/vim
patch 7.4.1422
Problem: Error when reading fails uses wrong errno. Keeping channel open after job stops results in test failing. Solution: Move the error up. Add ch_job_killed.
This commit is contained in:
@@ -307,11 +307,14 @@ add_channel(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return TRUE if "channel" has a callback.
|
* Return TRUE if "channel" has a callback and the associated job wasn't
|
||||||
|
* killed.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
channel_has_callback(channel_T *channel)
|
channel_still_useful(channel_T *channel)
|
||||||
{
|
{
|
||||||
|
if (channel->ch_job_killed && channel->ch_job == NULL)
|
||||||
|
return FALSE;
|
||||||
return channel->ch_callback != NULL
|
return channel->ch_callback != NULL
|
||||||
#ifdef CHANNEL_PIPES
|
#ifdef CHANNEL_PIPES
|
||||||
|| channel->ch_part[PART_OUT].ch_callback != NULL
|
|| channel->ch_part[PART_OUT].ch_callback != NULL
|
||||||
@@ -322,12 +325,13 @@ channel_has_callback(channel_T *channel)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Close a channel and free all its resources if there is no further action
|
* Close a channel and free all its resources if there is no further action
|
||||||
* possible, there is no callback to be invoked.
|
* possible, there is no callback to be invoked or the associated job was
|
||||||
|
* killed.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
channel_may_free(channel_T *channel)
|
channel_may_free(channel_T *channel)
|
||||||
{
|
{
|
||||||
if (!channel_has_callback(channel))
|
if (!channel_still_useful(channel))
|
||||||
channel_free(channel);
|
channel_free(channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1774,6 +1778,12 @@ channel_read(channel_T *channel, int part, char *func)
|
|||||||
* -> channel_read()
|
* -> channel_read()
|
||||||
*/
|
*/
|
||||||
ch_errors(channel, "%s(): Cannot read", func);
|
ch_errors(channel, "%s(): Cannot read", func);
|
||||||
|
if (len < 0)
|
||||||
|
{
|
||||||
|
ch_error(channel, "channel_read(): cannot read from channel");
|
||||||
|
PERROR(_("E896: read from channel"));
|
||||||
|
}
|
||||||
|
|
||||||
msg = channel->ch_part[part].ch_mode == MODE_RAW
|
msg = channel->ch_part[part].ch_mode == MODE_RAW
|
||||||
|| channel->ch_part[part].ch_mode == MODE_NL
|
|| channel->ch_part[part].ch_mode == MODE_NL
|
||||||
? DETACH_MSG_RAW : DETACH_MSG_JSON;
|
? DETACH_MSG_RAW : DETACH_MSG_JSON;
|
||||||
@@ -1785,12 +1795,6 @@ channel_read(channel_T *channel, int part, char *func)
|
|||||||
channel_close(channel, TRUE);
|
channel_close(channel, TRUE);
|
||||||
if (channel->ch_nb_close_cb != NULL)
|
if (channel->ch_nb_close_cb != NULL)
|
||||||
(*channel->ch_nb_close_cb)();
|
(*channel->ch_nb_close_cb)();
|
||||||
|
|
||||||
if (len < 0)
|
|
||||||
{
|
|
||||||
ch_error(channel, "channel_read(): cannot read from channel");
|
|
||||||
PERROR(_("E896: read from channel"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CH_HAS_GUI) && defined(FEAT_GUI_GTK)
|
#if defined(CH_HAS_GUI) && defined(FEAT_GUI_GTK)
|
||||||
@@ -2174,7 +2178,7 @@ channel_parse_messages(void)
|
|||||||
|
|
||||||
while (channel != NULL)
|
while (channel != NULL)
|
||||||
{
|
{
|
||||||
if (channel->ch_refcount == 0 && !channel_has_callback(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);
|
||||||
|
14
src/eval.c
14
src/eval.c
@@ -7770,8 +7770,11 @@ job_free(job_T *job)
|
|||||||
# ifdef FEAT_CHANNEL
|
# ifdef FEAT_CHANNEL
|
||||||
if (job->jv_channel != NULL)
|
if (job->jv_channel != NULL)
|
||||||
{
|
{
|
||||||
/* The channel doesn't count as a references for the job, we need to
|
/* The link from the channel to the job doesn't count as a reference,
|
||||||
* NULL the reference when the job is freed. */
|
* thus don't decrement the refcount of the job. The reference from
|
||||||
|
* the job to the channel does count the refrence, decrement it and
|
||||||
|
* NULL the reference. We don't set ch_job_killed, unreferencing the
|
||||||
|
* job doesn't mean it stops running. */
|
||||||
job->jv_channel->ch_job = NULL;
|
job->jv_channel->ch_job = NULL;
|
||||||
channel_unref(job->jv_channel);
|
channel_unref(job->jv_channel);
|
||||||
}
|
}
|
||||||
@@ -15161,7 +15164,14 @@ f_job_stop(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
|
|||||||
if (mch_stop_job(job, arg) == FAIL)
|
if (mch_stop_job(job, arg) == FAIL)
|
||||||
rettv->vval.v_number = 0;
|
rettv->vval.v_number = 0;
|
||||||
else
|
else
|
||||||
|
{
|
||||||
rettv->vval.v_number = 1;
|
rettv->vval.v_number = 1;
|
||||||
|
/* Assume that "hup" does not kill the job. */
|
||||||
|
if (job->jv_channel != NULL && STRCMP(arg, "hup") != 0)
|
||||||
|
job->jv_channel->ch_job_killed = TRUE;
|
||||||
|
}
|
||||||
|
/* We don't try freeing the job, obviously the caller still has a
|
||||||
|
* reference to it. */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -1373,6 +1373,8 @@ struct channel_S {
|
|||||||
job_T *ch_job; /* Job that uses this channel; this does not
|
job_T *ch_job; /* Job that uses this channel; this does not
|
||||||
* count as a reference to avoid a circular
|
* count as a reference to avoid a circular
|
||||||
* reference. */
|
* reference. */
|
||||||
|
int ch_job_killed; /* TRUE when there was a job and it was killed
|
||||||
|
* or we know it died. */
|
||||||
|
|
||||||
int ch_refcount; /* reference count */
|
int ch_refcount; /* reference count */
|
||||||
};
|
};
|
||||||
|
@@ -748,6 +748,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 */
|
||||||
|
/**/
|
||||||
|
1422,
|
||||||
/**/
|
/**/
|
||||||
1421,
|
1421,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user