summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2018-12-14 21:32:02 +0100
committerBram Moolenaar <Bram@vim.org>2018-12-14 21:32:02 +0100
commitcd1a62d468a55aca68deb3139d83530c7c23568d (patch)
tree37644066fac5d64c48b955b2f4436f051e661fe9
parent142a9758151e470307a80ea37b06ea34558ff5b3 (diff)
downloadvim-git-cd1a62d468a55aca68deb3139d83530c7c23568d.tar.gz
patch 8.1.0590: when a job ends the closed channels are not handledv8.1.0590
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)
-rw-r--r--src/channel.c15
-rw-r--r--src/misc2.c36
-rw-r--r--src/proto/channel.pro2
-rw-r--r--src/version.c2
4 files changed, 36 insertions, 19 deletions
diff --git a/src/channel.c b/src/channel.c
index 0ca6e5495..11ecc1685 100644
--- a/src/channel.c
+++ b/src/channel.c
@@ -5510,24 +5510,28 @@ has_pending_job(void)
/*
* 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)
{
int i;
+ int did_end = FALSE;
+ // be quick if there are no jobs to check
if (first_job == NULL)
- return;
+ return did_end;
for (i = 0; i < MAX_CHECK_ENDED; ++i)
{
- /* NOTE: mch_detect_ended_job() must only return a job of which the
- * status was just set to JOB_ENDED. */
+ // NOTE: mch_detect_ended_job() must only return a job of which the
+ // status was just set to JOB_ENDED.
job_T *job = mch_detect_ended_job(first_job);
if (job == NULL)
break;
- job_cleanup(job); /* may free "job" */
+ did_end = TRUE;
+ job_cleanup(job); // may free "job"
}
if (channel_need_redraw)
@@ -5535,6 +5539,7 @@ job_check_ended(void)
channel_need_redraw = FALSE;
redraw_after_callback(TRUE);
}
+ return did_end;
}
/*
diff --git a/src/misc2.c b/src/misc2.c
index 87799b0d0..fbf8a08af 100644
--- a/src/misc2.c
+++ b/src/misc2.c
@@ -6351,6 +6351,8 @@ has_non_ascii(char_u *s)
#endif
#if defined(MESSAGE_QUEUE) || defined(PROTO)
+# define MAX_REPEAT_PARSE 8
+
/*
* Process messages that have been queued for netbeans or clientserver.
* Also check if any jobs have ended.
@@ -6360,37 +6362,45 @@ has_non_ascii(char_u *s)
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
// change or be wiped while they are being redrawn.
if (updating_screen)
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)
- channel_handle_events(FALSE);
+ channel_handle_events(FALSE);
# endif
# ifdef FEAT_NETBEANS_INTG
- // Process the queued netbeans messages.
- netbeans_parse_messages();
+ // Process the queued netbeans messages.
+ netbeans_parse_messages();
# endif
# ifdef FEAT_JOB_CHANNEL
- // Write any buffer lines still to be written.
- channel_write_any_lines();
+ // Write any buffer lines still to be written.
+ channel_write_any_lines();
- // Process the messages queued on channels.
- channel_parse_messages();
+ // Process the messages queued on channels.
+ channel_parse_messages();
# endif
# if defined(FEAT_CLIENTSERVER) && defined(FEAT_X11)
- // Process the queued clientserver messages.
- server_parse_messages();
+ // Process the queued clientserver messages.
+ server_parse_messages();
# endif
# ifdef FEAT_JOB_CHANNEL
- // Check if any jobs have ended.
- job_check_ended();
+ // Check if any jobs have ended. If so, repeat the above to handle
+ // changes, e.g. stdin may have been closed.
+ if (job_check_ended())
+ continue;
# endif
+ break;
+ }
// 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.
diff --git a/src/proto/channel.pro b/src/proto/channel.pro
index 57b958ae1..e11cd3a14 100644
--- a/src/proto/channel.pro
+++ b/src/proto/channel.pro
@@ -65,7 +65,7 @@ job_T *job_alloc(void);
void job_set_options(job_T *job, jobopt_T *opt);
void job_stop_on_exit(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);
char *job_status(job_T *job);
void job_info(job_T *job, dict_T *dict);
diff --git a/src/version.c b/src/version.c
index f868e6abf..3ea9dc691 100644
--- a/src/version.c
+++ b/src/version.c
@@ -800,6 +800,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 590,
+/**/
589,
/**/
588,