1
0
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:
Bram Moolenaar
2016-02-26 11:17:46 +01:00
parent c8dcbb12c5
commit 46c85439c9
4 changed files with 31 additions and 13 deletions

View File

@@ -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);

View File

@@ -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

View File

@@ -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 */
}; };

View File

@@ -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,
/**/ /**/