To: vim_dev@googlegroups.com Subject: Patch 7.4.1536 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ 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 -- Bram@Moolenaar.net -- 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 ///