To: vim_dev@googlegroups.com Subject: Patch 8.0.1170 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.0.1170 Problem: Using termdebug results in 100% CPU time. (tomleb) Solution: Use polling instead of select(). Files: src/os_unix.c, src/channel.c, src/proto/channel.pro *** ../vim-8.0.1169/src/os_unix.c 2017-09-08 14:39:25.642102863 +0200 --- src/os_unix.c 2017-10-01 16:12:38.092839533 +0200 *************** *** 5330,5335 **** --- 5330,5338 ---- channel = add_channel(); if (channel == NULL) goto failed; + if (job->jv_tty_out != NULL) + ch_log(channel, "using pty %s on fd %d", + job->jv_tty_out, pty_master_fd); } BLOCK_SIGNALS(&curset); *************** *** 5702,5707 **** --- 5705,5713 ---- close(pty_master_fd); return FAIL; } + if (job->jv_tty_out != NULL) + ch_log(channel, "using pty %s on fd %d", + job->jv_tty_out, pty_master_fd); job->jv_channel = channel; /* ch_refcount was set by add_channel() */ channel->ch_keep_open = TRUE; *************** *** 5969,5975 **** } # endif #ifdef FEAT_JOB_CHANNEL ! nfd = channel_poll_setup(nfd, &fds); #endif if (interrupted != NULL) *interrupted = FALSE; --- 5975,5981 ---- } # endif #ifdef FEAT_JOB_CHANNEL ! nfd = channel_poll_setup(nfd, &fds, &towait); #endif if (interrupted != NULL) *interrupted = FALSE; *************** *** 6021,6027 **** } # endif #ifdef FEAT_JOB_CHANNEL ! if (ret > 0) ret = channel_poll_check(ret, &fds); #endif --- 6027,6034 ---- } # endif #ifdef FEAT_JOB_CHANNEL ! /* also call when ret == 0, we may be polling a keep-open channel */ ! if (ret >= 0) ret = channel_poll_check(ret, &fds); #endif *************** *** 6097,6103 **** } # endif # ifdef FEAT_JOB_CHANNEL ! maxfd = channel_select_setup(maxfd, &rfds, &wfds); # endif if (interrupted != NULL) *interrupted = FALSE; --- 6104,6110 ---- } # endif # ifdef FEAT_JOB_CHANNEL ! maxfd = channel_select_setup(maxfd, &rfds, &wfds, &tv, &tvp); # endif if (interrupted != NULL) *interrupted = FALSE; *************** *** 6183,6189 **** } # endif #ifdef FEAT_JOB_CHANNEL ! if (ret > 0) ret = channel_select_check(ret, &rfds, &wfds); #endif --- 6190,6197 ---- } # endif #ifdef FEAT_JOB_CHANNEL ! /* also call when ret == 0, we may be polling a keep-open channel */ ! if (ret >= 0) ret = channel_select_check(ret, &rfds, &wfds); #endif *** ../vim-8.0.1169/src/channel.c 2017-09-13 22:17:57.350938991 +0200 --- src/channel.c 2017-10-01 16:18:23.146651197 +0200 *************** *** 3960,3965 **** --- 3960,3967 ---- free_job_options(&opt); } + # define KEEP_OPEN_TIME 20 /* msec */ + # if (defined(UNIX) && !defined(HAVE_SELECT)) || defined(PROTO) /* * Add open channels to the poll struct. *************** *** 3967,3973 **** * The type of "fds" is hidden to avoid problems with the function proto. */ int ! channel_poll_setup(int nfd_in, void *fds_in) { int nfd = nfd_in; channel_T *channel; --- 3969,3975 ---- * The type of "fds" is hidden to avoid problems with the function proto. */ int ! channel_poll_setup(int nfd_in, void *fds_in, int *towait) { int nfd = nfd_in; channel_T *channel; *************** *** 3982,3991 **** if (ch_part->ch_fd != INVALID_FD) { ! ch_part->ch_poll_idx = nfd; ! fds[nfd].fd = ch_part->ch_fd; ! fds[nfd].events = POLLIN; ! nfd++; } else channel->ch_part[part].ch_poll_idx = -1; --- 3984,4004 ---- if (ch_part->ch_fd != INVALID_FD) { ! if (channel->ch_keep_open) ! { ! /* For unknown reason poll() returns immediately for a ! * keep-open channel. Instead of adding it to the fds add ! * a short timeout and check, like polling. */ ! if (*towait < 0 || *towait > KEEP_OPEN_TIME) ! *towait = KEEP_OPEN_TIME; ! } ! else ! { ! ch_part->ch_poll_idx = nfd; ! fds[nfd].fd = ch_part->ch_fd; ! fds[nfd].events = POLLIN; ! nfd++; ! } } else channel->ch_part[part].ch_poll_idx = -1; *************** *** 4021,4026 **** --- 4034,4045 ---- channel_read(channel, part, "channel_poll_check"); --ret; } + else if (channel->ch_part[part].ch_fd != INVALID_FD + && channel->ch_keep_open) + { + /* polling a keep-open channel */ + channel_read(channel, part, "channel_poll_check_keep_open"); + } } in_part = &channel->ch_part[PART_IN]; *************** *** 4037,4047 **** # endif /* UNIX && !HAVE_SELECT */ # if (!defined(WIN32) && defined(HAVE_SELECT)) || defined(PROTO) /* * The "fd_set" type is hidden to avoid problems with the function proto. */ int ! channel_select_setup(int maxfd_in, void *rfds_in, void *wfds_in) { int maxfd = maxfd_in; channel_T *channel; --- 4056,4072 ---- # endif /* UNIX && !HAVE_SELECT */ # if (!defined(WIN32) && defined(HAVE_SELECT)) || defined(PROTO) + /* * The "fd_set" type is hidden to avoid problems with the function proto. */ int ! channel_select_setup( ! int maxfd_in, ! void *rfds_in, ! void *wfds_in, ! struct timeval *tv, ! struct timeval **tvp) { int maxfd = maxfd_in; channel_T *channel; *************** *** 4057,4065 **** if (fd != INVALID_FD) { ! FD_SET((int)fd, rfds); ! if (maxfd < (int)fd) ! maxfd = (int)fd; } } } --- 4082,4106 ---- if (fd != INVALID_FD) { ! if (channel->ch_keep_open) ! { ! /* For unknown reason select() returns immediately for a ! * keep-open channel. Instead of adding it to the rfds add ! * a short timeout and check, like polling. */ ! if (*tvp == NULL || tv->tv_sec > 0 ! || tv->tv_usec > KEEP_OPEN_TIME * 1000) ! { ! *tvp = tv; ! tv->tv_sec = 0; ! tv->tv_usec = KEEP_OPEN_TIME * 1000; ! } ! } ! else ! { ! FD_SET((int)fd, rfds); ! if (maxfd < (int)fd) ! maxfd = (int)fd; ! } } } } *************** *** 4094,4099 **** --- 4135,4145 ---- FD_CLR(fd, rfds); --ret; } + else if (fd != INVALID_FD && channel->ch_keep_open) + { + /* polling a keep-open channel */ + channel_read(channel, part, "channel_select_check_keep_open"); + } } in_part = &channel->ch_part[PART_IN]; *** ../vim-8.0.1169/src/proto/channel.pro 2017-08-27 14:50:43.233759875 +0200 --- src/proto/channel.pro 2017-10-01 16:15:54.627592786 +0200 *************** *** 40,48 **** int channel_send(channel_T *channel, ch_part_T part, char_u *buf_arg, int len_arg, char *fun); void ch_expr_common(typval_T *argvars, typval_T *rettv, int eval); void ch_raw_common(typval_T *argvars, typval_T *rettv, int eval); ! int channel_poll_setup(int nfd_in, void *fds_in); int channel_poll_check(int ret_in, void *fds_in); ! int channel_select_setup(int maxfd_in, void *rfds_in, void *wfds_in); int channel_select_check(int ret_in, void *rfds_in, void *wfds_in); int channel_parse_messages(void); int channel_any_readahead(void); --- 40,48 ---- int channel_send(channel_T *channel, ch_part_T part, char_u *buf_arg, int len_arg, char *fun); void ch_expr_common(typval_T *argvars, typval_T *rettv, int eval); void ch_raw_common(typval_T *argvars, typval_T *rettv, int eval); ! int channel_poll_setup(int nfd_in, void *fds_in, int *towait); int channel_poll_check(int ret_in, void *fds_in); ! int channel_select_setup(int maxfd_in, void *rfds_in, void *wfds_in, struct timeval *tv, struct timeval **tvp); int channel_select_check(int ret_in, void *rfds_in, void *wfds_in); int channel_parse_messages(void); int channel_any_readahead(void); *** ../vim-8.0.1169/src/version.c 2017-10-01 14:34:58.577346624 +0200 --- src/version.c 2017-10-01 16:18:56.978436819 +0200 *************** *** 763,764 **** --- 763,766 ---- { /* Add new patch number below this line */ + /**/ + 1170, /**/ -- Eagles may soar, but weasels don't get sucked into jet engines. /// 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 ///