@@ -3960,14 +3960,16 @@ ch_raw_common(typval_T *argvars, typval_T *rettv, int eval)
39603960 free_job_options (& opt );
39613961}
39623962
3963+ # define KEEP_OPEN_TIME 20 /* msec */
3964+
39633965# if (defined(UNIX ) && !defined(HAVE_SELECT )) || defined(PROTO )
39643966/*
39653967 * Add open channels to the poll struct.
39663968 * Return the adjusted struct index.
39673969 * The type of "fds" is hidden to avoid problems with the function proto.
39683970 */
39693971 int
3970- channel_poll_setup (int nfd_in , void * fds_in )
3972+ channel_poll_setup (int nfd_in , void * fds_in , int * towait )
39713973{
39723974 int nfd = nfd_in ;
39733975 channel_T * channel ;
@@ -3982,10 +3984,21 @@ channel_poll_setup(int nfd_in, void *fds_in)
39823984
39833985 if (ch_part -> ch_fd != INVALID_FD )
39843986 {
3985- ch_part -> ch_poll_idx = nfd ;
3986- fds [nfd ].fd = ch_part -> ch_fd ;
3987- fds [nfd ].events = POLLIN ;
3988- nfd ++ ;
3987+ if (channel -> ch_keep_open )
3988+ {
3989+ /* For unknown reason poll() returns immediately for a
3990+ * keep-open channel. Instead of adding it to the fds add
3991+ * a short timeout and check, like polling. */
3992+ if (* towait < 0 || * towait > KEEP_OPEN_TIME )
3993+ * towait = KEEP_OPEN_TIME ;
3994+ }
3995+ else
3996+ {
3997+ ch_part -> ch_poll_idx = nfd ;
3998+ fds [nfd ].fd = ch_part -> ch_fd ;
3999+ fds [nfd ].events = POLLIN ;
4000+ nfd ++ ;
4001+ }
39894002 }
39904003 else
39914004 channel -> ch_part [part ].ch_poll_idx = -1 ;
@@ -4021,6 +4034,12 @@ channel_poll_check(int ret_in, void *fds_in)
40214034 channel_read (channel , part , "channel_poll_check" );
40224035 -- ret ;
40234036 }
4037+ else if (channel -> ch_part [part ].ch_fd != INVALID_FD
4038+ && channel -> ch_keep_open )
4039+ {
4040+ /* polling a keep-open channel */
4041+ channel_read (channel , part , "channel_poll_check_keep_open" );
4042+ }
40244043 }
40254044
40264045 in_part = & channel -> ch_part [PART_IN ];
@@ -4037,11 +4056,17 @@ channel_poll_check(int ret_in, void *fds_in)
40374056# endif /* UNIX && !HAVE_SELECT */
40384057
40394058# if (!defined(WIN32 ) && defined(HAVE_SELECT )) || defined(PROTO )
4059+
40404060/*
40414061 * The "fd_set" type is hidden to avoid problems with the function proto.
40424062 */
40434063 int
4044- channel_select_setup (int maxfd_in , void * rfds_in , void * wfds_in )
4064+ channel_select_setup (
4065+ int maxfd_in ,
4066+ void * rfds_in ,
4067+ void * wfds_in ,
4068+ struct timeval * tv ,
4069+ struct timeval * * tvp )
40454070{
40464071 int maxfd = maxfd_in ;
40474072 channel_T * channel ;
@@ -4057,9 +4082,25 @@ channel_select_setup(int maxfd_in, void *rfds_in, void *wfds_in)
40574082
40584083 if (fd != INVALID_FD )
40594084 {
4060- FD_SET ((int )fd , rfds );
4061- if (maxfd < (int )fd )
4062- maxfd = (int )fd ;
4085+ if (channel -> ch_keep_open )
4086+ {
4087+ /* For unknown reason select() returns immediately for a
4088+ * keep-open channel. Instead of adding it to the rfds add
4089+ * a short timeout and check, like polling. */
4090+ if (* tvp == NULL || tv -> tv_sec > 0
4091+ || tv -> tv_usec > KEEP_OPEN_TIME * 1000 )
4092+ {
4093+ * tvp = tv ;
4094+ tv -> tv_sec = 0 ;
4095+ tv -> tv_usec = KEEP_OPEN_TIME * 1000 ;
4096+ }
4097+ }
4098+ else
4099+ {
4100+ FD_SET ((int )fd , rfds );
4101+ if (maxfd < (int )fd )
4102+ maxfd = (int )fd ;
4103+ }
40634104 }
40644105 }
40654106 }
@@ -4094,6 +4135,11 @@ channel_select_check(int ret_in, void *rfds_in, void *wfds_in)
40944135 FD_CLR (fd , rfds );
40954136 -- ret ;
40964137 }
4138+ else if (fd != INVALID_FD && channel -> ch_keep_open )
4139+ {
4140+ /* polling a keep-open channel */
4141+ channel_read (channel , part , "channel_select_check_keep_open" );
4142+ }
40974143 }
40984144
40994145 in_part = & channel -> ch_part [PART_IN ];
0 commit comments