]> granicus.if.org Git - vim/commitdiff
patch 8.1.0590: when a job ends the closed channels are not handled v8.1.0590
authorBram Moolenaar <Bram@vim.org>
Fri, 14 Dec 2018 20:32:02 +0000 (21:32 +0100)
committerBram Moolenaar <Bram@vim.org>
Fri, 14 Dec 2018 20:32:02 +0000 (21:32 +0100)
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)

src/channel.c
src/misc2.c
src/proto/channel.pro
src/version.c

index 0ca6e549544b74a74e03b7987ea69a66f5673575..11ecc168597e1e56e151c84b6d1d8ac823bd20b1 100644 (file)
@@ -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;
 }
 
 /*
index 87799b0d0e4c8ef948c8d28ca3f4e647ccfac644..fbf8a08afab29562bf453d535de766299a9ced92 100644 (file)
@@ -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.
index 57b958ae105016b01d706ee61a410a97c5bb0a6d..e11cd3a14fd60e4ead6abb315fbf6b4ab223c06e 100644 (file)
@@ -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);
index f868e6abf97439020611f847e66300f34fcaa036..3ea9dc691b593861ba8e33cba9ee460e296e6516 100644 (file)
@@ -799,6 +799,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    590,
 /**/
     589,
 /**/