@@ -3985,14 +3985,16 @@ ch_raw_common(typval_T *argvars, typval_T *rettv, int eval)
39853985 free_job_options (& opt );
39863986}
39873987
3988+ # define KEEP_OPEN_TIME 20 /* msec */
3989+
39883990# if (defined(UNIX ) && !defined(HAVE_SELECT )) || defined(PROTO )
39893991/*
39903992 * Add open channels to the poll struct.
39913993 * Return the adjusted struct index.
39923994 * The type of "fds" is hidden to avoid problems with the function proto.
39933995 */
39943996 int
3995- channel_poll_setup (int nfd_in , void * fds_in )
3997+ channel_poll_setup (int nfd_in , void * fds_in , int * towait )
39963998{
39973999 int nfd = nfd_in ;
39984000 channel_T * channel ;
@@ -4007,10 +4009,21 @@ channel_poll_setup(int nfd_in, void *fds_in)
40074009
40084010 if (ch_part -> ch_fd != INVALID_FD )
40094011 {
4010- ch_part -> ch_poll_idx = nfd ;
4011- fds [nfd ].fd = ch_part -> ch_fd ;
4012- fds [nfd ].events = POLLIN ;
4013- nfd ++ ;
4012+ if (channel -> ch_keep_open )
4013+ {
4014+ /* For unknown reason poll() returns immediately for a
4015+ * keep-open channel. Instead of adding it to the fds add
4016+ * a short timeout and check, like polling. */
4017+ if (* towait < 0 || * towait > KEEP_OPEN_TIME )
4018+ * towait = KEEP_OPEN_TIME ;
4019+ }
4020+ else
4021+ {
4022+ ch_part -> ch_poll_idx = nfd ;
4023+ fds [nfd ].fd = ch_part -> ch_fd ;
4024+ fds [nfd ].events = POLLIN ;
4025+ nfd ++ ;
4026+ }
40144027 }
40154028 else
40164029 channel -> ch_part [part ].ch_poll_idx = -1 ;
@@ -4046,6 +4059,12 @@ channel_poll_check(int ret_in, void *fds_in)
40464059 channel_read (channel , part , "channel_poll_check" );
40474060 -- ret ;
40484061 }
4062+ else if (channel -> ch_part [part ].ch_fd != INVALID_FD
4063+ && channel -> ch_keep_open )
4064+ {
4065+ /* polling a keep-open channel */
4066+ channel_read (channel , part , "channel_poll_check_keep_open" );
4067+ }
40494068 }
40504069
40514070 in_part = & channel -> ch_part [PART_IN ];
@@ -4062,11 +4081,17 @@ channel_poll_check(int ret_in, void *fds_in)
40624081# endif /* UNIX && !HAVE_SELECT */
40634082
40644083# if (!defined(WIN32 ) && defined(HAVE_SELECT )) || defined(PROTO )
4084+
40654085/*
40664086 * The "fd_set" type is hidden to avoid problems with the function proto.
40674087 */
40684088 int
4069- channel_select_setup (int maxfd_in , void * rfds_in , void * wfds_in )
4089+ channel_select_setup (
4090+ int maxfd_in ,
4091+ void * rfds_in ,
4092+ void * wfds_in ,
4093+ struct timeval * tv ,
4094+ struct timeval * * tvp )
40704095{
40714096 int maxfd = maxfd_in ;
40724097 channel_T * channel ;
@@ -4082,9 +4107,25 @@ channel_select_setup(int maxfd_in, void *rfds_in, void *wfds_in)
40824107
40834108 if (fd != INVALID_FD )
40844109 {
4085- FD_SET ((int )fd , rfds );
4086- if (maxfd < (int )fd )
4087- maxfd = (int )fd ;
4110+ if (channel -> ch_keep_open )
4111+ {
4112+ /* For unknown reason select() returns immediately for a
4113+ * keep-open channel. Instead of adding it to the rfds add
4114+ * a short timeout and check, like polling. */
4115+ if (* tvp == NULL || tv -> tv_sec > 0
4116+ || tv -> tv_usec > KEEP_OPEN_TIME * 1000 )
4117+ {
4118+ * tvp = tv ;
4119+ tv -> tv_sec = 0 ;
4120+ tv -> tv_usec = KEEP_OPEN_TIME * 1000 ;
4121+ }
4122+ }
4123+ else
4124+ {
4125+ FD_SET ((int )fd , rfds );
4126+ if (maxfd < (int )fd )
4127+ maxfd = (int )fd ;
4128+ }
40884129 }
40894130 }
40904131 }
@@ -4119,6 +4160,11 @@ channel_select_check(int ret_in, void *rfds_in, void *wfds_in)
41194160 FD_CLR (fd , rfds );
41204161 -- ret ;
41214162 }
4163+ else if (fd != INVALID_FD && channel -> ch_keep_open )
4164+ {
4165+ /* polling a keep-open channel */
4166+ channel_read (channel , part , "channel_select_check_keep_open" );
4167+ }
41224168 }
41234169
41244170 in_part = & channel -> ch_part [PART_IN ];
0 commit comments