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. */
# endif
}
- void
+ static 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
channel_gui_register(channel);
}
+ 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)
{
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
+ channel_gui_unregister_one(channel, part);
}
}
channel->ch_nb_close_cb = nb_close_cb;
#ifdef FEAT_GUI
- channel_gui_register(channel);
+ 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)
{
- channel->CH_IN_FD = in;
- channel->CH_OUT_FD = out;
- channel->CH_ERR_FD = 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
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;
- }
+ 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)
if (!use_null_for_in || !use_null_for_out || !use_null_for_err)
{
- channel = add_channel();
+ 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;
}
job->jv_pid = pid;
job->jv_status = JOB_STARTED;
# ifdef FEAT_CHANNEL
- job->jv_channel = channel;
+ job->jv_channel = channel; /* ch_refcount was set above */
# endif
# ifdef FEAT_CHANNEL
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
failed: ;
# ifdef FEAT_CHANNEL
- if (channel != NULL)
- channel_free(channel);
+ channel_unref(channel);
if (fd_in[0] >= 0)
close(fd_in[0]);
if (fd_in[1] >= 0)
if (!use_null_for_in || !use_null_for_out || !use_null_for_err)
{
- channel = add_channel();
+ 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;
}
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;
CloseHandle(ifd[1]);
CloseHandle(ofd[1]);
CloseHandle(efd[1]);
- channel_free(channel);
+ channel_unref(channel);
# else
; /* make compiler happy */
# endif
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 = ''