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.