Patch 7.4.1536
Problem:    Cannot re-use a channel for another job.
Solution:   Add the "channel" option to job_start().
Files:      src/channel.c, src/eval.c, src/structs.h, src/os_unix.c,
            src/os_win32.c, src/proto/channel.pro,
            src/testdir/test_channel.vim


*** ../vim-7.4.1535/src/channel.c       2016-03-10 21:10:54.452368808 +0100
--- src/channel.c       2016-03-11 22:05:51.815636063 +0100
***************
*** 459,464 ****
--- 459,467 ----
      static void
  channel_gui_register_one(channel_T *channel, int part)
  {
+     if (!CH_HAS_GUI)
+       return;
+ 
  # ifdef FEAT_GUI_X11
      /* Tell notifier we are interested in being called
       * when there is input on the editor connection socket. */
***************
*** 499,510 ****
  # endif
  }
  
!     void
  channel_gui_register(channel_T *channel)
  {
-     if (!CH_HAS_GUI)
-       return;
- 
      if (channel->CH_SOCK_FD != INVALID_FD)
        channel_gui_register_one(channel, PART_SOCK);
  # ifdef CHANNEL_PIPES
--- 502,510 ----
  # endif
  }
  
!     static void
  channel_gui_register(channel_T *channel)
  {
      if (channel->CH_SOCK_FD != INVALID_FD)
        channel_gui_register_one(channel, PART_SOCK);
  # ifdef CHANNEL_PIPES
***************
*** 529,534 ****
--- 529,558 ----
  }
  
      static void
+ channel_gui_unregister_one(channel_T *channel, int part)
+ {
+ # ifdef FEAT_GUI_X11
+     if (channel->ch_part[part].ch_inputHandler != (XtInputId)NULL)
+     {
+       XtRemoveInput(channel->ch_part[part].ch_inputHandler);
+       channel->ch_part[part].ch_inputHandler = (XtInputId)NULL;
+     }
+ # else
+ #  ifdef FEAT_GUI_GTK
+     if (channel->ch_part[part].ch_inputHandler != 0)
+     {
+ #   if GTK_CHECK_VERSION(3,0,0)
+       g_source_remove(channel->ch_part[part].ch_inputHandler);
+ #   else
+       gdk_input_remove(channel->ch_part[part].ch_inputHandler);
+ #   endif
+       channel->ch_part[part].ch_inputHandler = 0;
+     }
+ #  endif
+ # endif
+ }
+ 
+     static void
  channel_gui_unregister(channel_T *channel)
  {
      int           part;
***************
*** 539,563 ****
      part = PART_SOCK;
  #endif
      {
! # ifdef FEAT_GUI_X11
!       if (channel->ch_part[part].ch_inputHandler != (XtInputId)NULL)
!       {
!           XtRemoveInput(channel->ch_part[part].ch_inputHandler);
!           channel->ch_part[part].ch_inputHandler = (XtInputId)NULL;
!       }
! # else
! #  ifdef FEAT_GUI_GTK
!       if (channel->ch_part[part].ch_inputHandler != 0)
!       {
! #   if GTK_CHECK_VERSION(3,0,0)
!           g_source_remove(channel->ch_part[part].ch_inputHandler);
! #   else
!           gdk_input_remove(channel->ch_part[part].ch_inputHandler);
! #   endif
!           channel->ch_part[part].ch_inputHandler = 0;
!       }
! #  endif
! # endif
      }
  }
  
--- 563,569 ----
      part = PART_SOCK;
  #endif
      {
!       channel_gui_unregister_one(channel, part);
      }
  }
  
***************
*** 830,848 ****
      channel->ch_nb_close_cb = nb_close_cb;
  
  #ifdef FEAT_GUI
!     channel_gui_register(channel);
  #endif
  
      return channel;
  }
  
  #if defined(CHANNEL_PIPES) || defined(PROTO)
      void
  channel_set_pipes(channel_T *channel, sock_T in, sock_T out, sock_T err)
  {
!     channel->CH_IN_FD = in;
!     channel->CH_OUT_FD = out;
!     channel->CH_ERR_FD = err;
  }
  #endif
  
--- 836,888 ----
      channel->ch_nb_close_cb = nb_close_cb;
  
  #ifdef FEAT_GUI
!     channel_gui_register_one(channel, PART_SOCK);
  #endif
  
      return channel;
  }
  
  #if defined(CHANNEL_PIPES) || defined(PROTO)
+     static void
+ may_close_part(sock_T *fd)
+ {
+     if (*fd != INVALID_FD)
+     {
+       fd_close(*fd);
+       *fd = INVALID_FD;
+     }
+ }
+ 
      void
  channel_set_pipes(channel_T *channel, sock_T in, sock_T out, sock_T err)
  {
!     if (in != INVALID_FD)
!     {
!       may_close_part(&channel->CH_IN_FD);
!       channel->CH_IN_FD = in;
!     }
!     if (out != INVALID_FD)
!     {
! # if defined(FEAT_GUI)
!       channel_gui_unregister_one(channel, PART_OUT);
! # endif
!       may_close_part(&channel->CH_OUT_FD);
!       channel->CH_OUT_FD = out;
! # if defined(FEAT_GUI)
!       channel_gui_register_one(channel, PART_OUT);
! # endif
!     }
!     if (err != INVALID_FD)
!     {
! # if defined(FEAT_GUI)
!       channel_gui_unregister_one(channel, PART_ERR);
! # endif
!       may_close_part(&channel->CH_ERR_FD);
!       channel->CH_ERR_FD = err;
! # if defined(FEAT_GUI)
!       channel_gui_register_one(channel, PART_ERR);
! # endif
!     }
  }
  #endif
  
***************
*** 1912,1932 ****
        channel->CH_SOCK_FD = INVALID_FD;
      }
  #if defined(CHANNEL_PIPES)
!     if (channel->CH_IN_FD != INVALID_FD)
!     {
!       fd_close(channel->CH_IN_FD);
!       channel->CH_IN_FD = INVALID_FD;
!     }
!     if (channel->CH_OUT_FD != INVALID_FD)
!     {
!       fd_close(channel->CH_OUT_FD);
!       channel->CH_OUT_FD = INVALID_FD;
!     }
!     if (channel->CH_ERR_FD != INVALID_FD)
!     {
!       fd_close(channel->CH_ERR_FD);
!       channel->CH_ERR_FD = INVALID_FD;
!     }
  #endif
  
      if (invoke_close_cb && channel->ch_close_cb != NULL)
--- 1952,1960 ----
        channel->CH_SOCK_FD = INVALID_FD;
      }
  #if defined(CHANNEL_PIPES)
!     may_close_part(&channel->CH_IN_FD);
!     may_close_part(&channel->CH_OUT_FD);
!     may_close_part(&channel->CH_ERR_FD);
  #endif
  
      if (invoke_close_cb && channel->ch_close_cb != NULL)
*** ../vim-7.4.1535/src/eval.c  2016-03-11 19:31:41.141336198 +0100
--- src/eval.c  2016-03-11 21:23:52.398267855 +0100
***************
*** 10164,10169 ****
--- 10164,10181 ----
                    return FAIL;
                }
            }
+           else if (STRCMP(hi->hi_key, "channel") == 0)
+           {
+               if (!(supported & JO_OUT_IO))
+                   break;
+               opt->jo_set |= JO_CHANNEL;
+               if (item->v_type != VAR_CHANNEL)
+               {
+                   EMSG2(_(e_invarg2), "channel");
+                   return FAIL;
+               }
+               opt->jo_channel = item->vval.v_channel;
+           }
            else if (STRCMP(hi->hi_key, "callback") == 0)
            {
                if (!(supported & JO_CALLBACK))
*** ../vim-7.4.1535/src/structs.h       2016-03-09 23:14:02.291262052 +0100
--- src/structs.h       2016-03-11 21:20:47.916224392 +0100
***************
*** 1412,1417 ****
--- 1412,1418 ----
  #define JO_OUT_BUF        0x1000000   /* "out-buf" */
  #define JO_ERR_BUF        0x2000000   /* "err-buf" (JO_OUT_BUF << 1) */
  #define JO_IN_BUF         0x4000000   /* "in-buf" (JO_OUT_BUF << 2) */
+ #define JO_CHANNEL        0x8000000   /* "channel" */
  #define JO_ALL                    0xfffffff
  
  #define JO_MODE_ALL   (JO_MODE + JO_IN_MODE + JO_OUT_MODE + JO_ERR_MODE)
***************
*** 1443,1448 ****
--- 1444,1450 ----
      char_u    jo_io_name_buf[4][NUMBUFLEN];
      char_u    *jo_io_name[4]; /* not allocated! */
      int               jo_io_buf[4];
+     channel_T *jo_channel;
  
      linenr_T  jo_in_top;
      linenr_T  jo_in_bot;
*** ../vim-7.4.1535/src/os_unix.c       2016-03-08 18:27:16.869343475 +0100
--- src/os_unix.c       2016-03-11 22:01:20.654499928 +0100
***************
*** 5111,5117 ****
  
      if (!use_null_for_in || !use_null_for_out || !use_null_for_err)
      {
!       channel = add_channel();
        if (channel == NULL)
            goto failed;
      }
--- 5111,5124 ----
  
      if (!use_null_for_in || !use_null_for_out || !use_null_for_err)
      {
!       if (options->jo_set & JO_CHANNEL)
!       {
!           channel = options->jo_channel;
!           if (channel != NULL)
!               ++channel->ch_refcount;
!       }
!       else
!           channel = add_channel();
        if (channel == NULL)
            goto failed;
      }
***************
*** 5211,5217 ****
      job->jv_pid = pid;
      job->jv_status = JOB_STARTED;
  # ifdef FEAT_CHANNEL
!     job->jv_channel = channel;
  # endif
  
  # ifdef FEAT_CHANNEL
--- 5218,5224 ----
      job->jv_pid = pid;
      job->jv_status = JOB_STARTED;
  # ifdef FEAT_CHANNEL
!     job->jv_channel = channel;  /* ch_refcount was set above */
  # endif
  
  # ifdef FEAT_CHANNEL
***************
*** 5232,5240 ****
                      use_out_for_err || use_file_for_err || use_null_for_err
                                                    ? INVALID_FD : fd_err[0]);
        channel_set_job(channel, job, options);
- #  ifdef FEAT_GUI
-       channel_gui_register(channel);
- #  endif
      }
  # endif
  
--- 5239,5244 ----
***************
*** 5243,5250 ****
  
  failed: ;
  # ifdef FEAT_CHANNEL
!     if (channel != NULL)
!       channel_free(channel);
      if (fd_in[0] >= 0)
        close(fd_in[0]);
      if (fd_in[1] >= 0)
--- 5247,5253 ----
  
  failed: ;
  # ifdef FEAT_CHANNEL
!     channel_unref(channel);
      if (fd_in[0] >= 0)
        close(fd_in[0]);
      if (fd_in[1] >= 0)
*** ../vim-7.4.1535/src/os_win32.c      2016-03-10 21:45:59.554192736 +0100
--- src/os_win32.c      2016-03-11 22:01:15.310556376 +0100
***************
*** 5138,5144 ****
  
      if (!use_null_for_in || !use_null_for_out || !use_null_for_err)
      {
!       channel = add_channel();
        if (channel == NULL)
            goto failed;
      }
--- 5138,5151 ----
  
      if (!use_null_for_in || !use_null_for_out || !use_null_for_err)
      {
!       if (options->jo_set & JO_CHANNEL)
!       {
!           channel = options->jo_channel;
!           if (channel != NULL)
!               ++channel->ch_refcount;
!       }
!       else
!           channel = add_channel();
        if (channel == NULL)
            goto failed;
      }
***************
*** 5188,5196 ****
                      use_out_for_err || use_file_for_err || use_null_for_err
                                            ? INVALID_FD : (sock_T)efd[0]);
        channel_set_job(channel, job, options);
- #  ifdef FEAT_GUI
-       channel_gui_register(channel);
- #  endif
      }
  # endif
      return;
--- 5195,5200 ----
***************
*** 5203,5209 ****
      CloseHandle(ifd[1]);
      CloseHandle(ofd[1]);
      CloseHandle(efd[1]);
!     channel_free(channel);
  # else
      ;  /* make compiler happy */
  # endif
--- 5207,5213 ----
      CloseHandle(ifd[1]);
      CloseHandle(ofd[1]);
      CloseHandle(efd[1]);
!     channel_unref(channel);
  # else
      ;  /* make compiler happy */
  # endif
*** ../vim-7.4.1535/src/proto/channel.pro       2016-03-06 20:22:20.356165934 
+0100
--- src/proto/channel.pro       2016-03-11 22:04:04.272771781 +0100
***************
*** 6,12 ****
  channel_T *add_channel(void);
  int channel_may_free(channel_T *channel);
  void channel_free(channel_T *channel);
- void channel_gui_register(channel_T *channel);
  void channel_gui_register_all(void);
  channel_T *channel_open(char *hostname, int port_in, int waittime, void 
(*nb_close_cb)(void));
  void channel_set_pipes(channel_T *channel, sock_T in, sock_T out, sock_T err);
--- 6,11 ----
*** ../vim-7.4.1535/src/testdir/test_channel.vim        2016-03-09 
23:14:02.299261966 +0100
--- src/testdir/test_channel.vim        2016-03-11 22:11:05.880320039 +0100
***************
*** 917,922 ****
--- 917,949 ----
    call job_stop(job)
  endfunc
  
+ func Test_reuse_channel()
+   if !has('job')
+     return
+   endif
+   call ch_log('Test_reuse_channel()')
+ 
+   let job = job_start(s:python . " test_channel_pipe.py")
+   call assert_equal("run", job_status(job))
+   let handle = job_getchannel(job)
+   try
+     call ch_sendraw(handle, "echo something\n")
+     call assert_equal("something", ch_readraw(handle))
+   finally
+     call job_stop(job)
+   endtry
+ 
+   let job = job_start(s:python . " test_channel_pipe.py", {'channel': handle})
+   call assert_equal("run", job_status(job))
+   let handle = job_getchannel(job)
+   try
+     call ch_sendraw(handle, "echo again\n")
+     call assert_equal("again", ch_readraw(handle))
+   finally
+     call job_stop(job)
+   endtry
+ endfunc
+ 
  """"""""""
  
  let s:unletResponse = ''
*** ../vim-7.4.1535/src/version.c       2016-03-11 19:31:41.141336198 +0100
--- src/version.c       2016-03-11 22:19:26.779032904 +0100
***************
*** 745,746 ****
--- 745,748 ----
  {   /* Add new patch number below this line */
+ /**/
+     1536,
  /**/

-- 
How To Keep A Healthy Level Of Insanity:
11. Specify that your drive-through order is "to go".

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui