1
0
forked from aniani/vim

patch 8.1.0590: when a job ends the closed channels are not handled

Problem:    When a job ends the closed channels are not handled.
Solution:   When a job is detected to have ended, check the channels again.
            (closes #3530)
This commit is contained in:
Bram Moolenaar
2018-12-14 21:32:02 +01:00
parent 142a975815
commit cd1a62d468
4 changed files with 36 additions and 19 deletions

View File

@@ -5510,24 +5510,28 @@ has_pending_job(void)
/* /*
* Called once in a while: check if any jobs that seem useful have ended. * Called once in a while: check if any jobs that seem useful have ended.
* Returns TRUE if a job did end.
*/ */
void int
job_check_ended(void) job_check_ended(void)
{ {
int i; int i;
int did_end = FALSE;
// be quick if there are no jobs to check
if (first_job == NULL) if (first_job == NULL)
return; return did_end;
for (i = 0; i < MAX_CHECK_ENDED; ++i) for (i = 0; i < MAX_CHECK_ENDED; ++i)
{ {
/* NOTE: mch_detect_ended_job() must only return a job of which the // NOTE: mch_detect_ended_job() must only return a job of which the
* status was just set to JOB_ENDED. */ // status was just set to JOB_ENDED.
job_T *job = mch_detect_ended_job(first_job); job_T *job = mch_detect_ended_job(first_job);
if (job == NULL) if (job == NULL)
break; break;
job_cleanup(job); /* may free "job" */ did_end = TRUE;
job_cleanup(job); // may free "job"
} }
if (channel_need_redraw) if (channel_need_redraw)
@@ -5535,6 +5539,7 @@ job_check_ended(void)
channel_need_redraw = FALSE; channel_need_redraw = FALSE;
redraw_after_callback(TRUE); redraw_after_callback(TRUE);
} }
return did_end;
} }
/* /*

View File

@@ -6351,6 +6351,8 @@ has_non_ascii(char_u *s)
#endif #endif
#if defined(MESSAGE_QUEUE) || defined(PROTO) #if defined(MESSAGE_QUEUE) || defined(PROTO)
# define MAX_REPEAT_PARSE 8
/* /*
* Process messages that have been queued for netbeans or clientserver. * Process messages that have been queued for netbeans or clientserver.
* Also check if any jobs have ended. * Also check if any jobs have ended.
@@ -6360,37 +6362,45 @@ has_non_ascii(char_u *s)
void void
parse_queued_messages(void) parse_queued_messages(void)
{ {
win_T *old_curwin = curwin; win_T *old_curwin = curwin;
int i;
// Do not handle messages while redrawing, because it may cause buffers to // Do not handle messages while redrawing, because it may cause buffers to
// change or be wiped while they are being redrawn. // change or be wiped while they are being redrawn.
if (updating_screen) if (updating_screen)
return; return;
// For Win32 mch_breakcheck() does not check for input, do it here. // Loop when a job ended, but don't keep looping forever.
for (i = 0; i < MAX_REPEAT_PARSE; ++i)
{
// For Win32 mch_breakcheck() does not check for input, do it here.
# if defined(WIN32) && defined(FEAT_JOB_CHANNEL) # if defined(WIN32) && defined(FEAT_JOB_CHANNEL)
channel_handle_events(FALSE); channel_handle_events(FALSE);
# endif # endif
# ifdef FEAT_NETBEANS_INTG # ifdef FEAT_NETBEANS_INTG
// Process the queued netbeans messages. // Process the queued netbeans messages.
netbeans_parse_messages(); netbeans_parse_messages();
# endif # endif
# ifdef FEAT_JOB_CHANNEL # ifdef FEAT_JOB_CHANNEL
// Write any buffer lines still to be written. // Write any buffer lines still to be written.
channel_write_any_lines(); channel_write_any_lines();
// Process the messages queued on channels. // Process the messages queued on channels.
channel_parse_messages(); channel_parse_messages();
# endif # endif
# if defined(FEAT_CLIENTSERVER) && defined(FEAT_X11) # if defined(FEAT_CLIENTSERVER) && defined(FEAT_X11)
// Process the queued clientserver messages. // Process the queued clientserver messages.
server_parse_messages(); server_parse_messages();
# endif # endif
# ifdef FEAT_JOB_CHANNEL # ifdef FEAT_JOB_CHANNEL
// Check if any jobs have ended. // Check if any jobs have ended. If so, repeat the above to handle
job_check_ended(); // changes, e.g. stdin may have been closed.
if (job_check_ended())
continue;
# endif # endif
break;
}
// If the current window changed we need to bail out of the waiting loop. // If the current window changed we need to bail out of the waiting loop.
// E.g. when a job exit callback closes the terminal window. // E.g. when a job exit callback closes the terminal window.

View File

@@ -65,7 +65,7 @@ job_T *job_alloc(void);
void job_set_options(job_T *job, jobopt_T *opt); void job_set_options(job_T *job, jobopt_T *opt);
void job_stop_on_exit(void); void job_stop_on_exit(void);
int has_pending_job(void); int has_pending_job(void);
void job_check_ended(void); int job_check_ended(void);
job_T *job_start(typval_T *argvars, char **argv_arg, jobopt_T *opt_arg, int is_terminal); job_T *job_start(typval_T *argvars, char **argv_arg, jobopt_T *opt_arg, int is_terminal);
char *job_status(job_T *job); char *job_status(job_T *job);
void job_info(job_T *job, dict_T *dict); void job_info(job_T *job, dict_T *dict);

View File

@@ -799,6 +799,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 */
/**/
590,
/**/ /**/
589, 589,
/**/ /**/