comparison src/channel.c @ 12584:f28067b83dec v8.0.1170

patch 8.0.1170: using termdebug results in 100% CPU time commit https://github.com/vim/vim/commit/f33606112a59de6965692840b47d9cb4b924fc97 Author: Bram Moolenaar <Bram@vim.org> Date: Sun Oct 1 16:21:31 2017 +0200 patch 8.0.1170: using termdebug results in 100% CPU time Problem: Using termdebug results in 100% CPU time. (tomleb) Solution: Use polling instead of select().
author Christian Brabandt <cb@256bit.org>
date Sun, 01 Oct 2017 16:30:03 +0200
parents 579faede5d9c
children 60e1e4cfb21e
comparison
equal deleted inserted replaced
12583:ccd0799982bd 12584:f28067b83dec
3958 rettv->vval.v_string = channel_read_block(channel, part_read, timeout); 3958 rettv->vval.v_string = channel_read_block(channel, part_read, timeout);
3959 } 3959 }
3960 free_job_options(&opt); 3960 free_job_options(&opt);
3961 } 3961 }
3962 3962
3963 # define KEEP_OPEN_TIME 20 /* msec */
3964
3963 # if (defined(UNIX) && !defined(HAVE_SELECT)) || defined(PROTO) 3965 # if (defined(UNIX) && !defined(HAVE_SELECT)) || defined(PROTO)
3964 /* 3966 /*
3965 * Add open channels to the poll struct. 3967 * Add open channels to the poll struct.
3966 * Return the adjusted struct index. 3968 * Return the adjusted struct index.
3967 * The type of "fds" is hidden to avoid problems with the function proto. 3969 * The type of "fds" is hidden to avoid problems with the function proto.
3968 */ 3970 */
3969 int 3971 int
3970 channel_poll_setup(int nfd_in, void *fds_in) 3972 channel_poll_setup(int nfd_in, void *fds_in, int *towait)
3971 { 3973 {
3972 int nfd = nfd_in; 3974 int nfd = nfd_in;
3973 channel_T *channel; 3975 channel_T *channel;
3974 struct pollfd *fds = fds_in; 3976 struct pollfd *fds = fds_in;
3975 ch_part_T part; 3977 ch_part_T part;
3980 { 3982 {
3981 chanpart_T *ch_part = &channel->ch_part[part]; 3983 chanpart_T *ch_part = &channel->ch_part[part];
3982 3984
3983 if (ch_part->ch_fd != INVALID_FD) 3985 if (ch_part->ch_fd != INVALID_FD)
3984 { 3986 {
3985 ch_part->ch_poll_idx = nfd; 3987 if (channel->ch_keep_open)
3986 fds[nfd].fd = ch_part->ch_fd; 3988 {
3987 fds[nfd].events = POLLIN; 3989 /* For unknown reason poll() returns immediately for a
3988 nfd++; 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 }
3989 } 4002 }
3990 else 4003 else
3991 channel->ch_part[part].ch_poll_idx = -1; 4004 channel->ch_part[part].ch_poll_idx = -1;
3992 } 4005 }
3993 } 4006 }
4019 if (ret > 0 && idx != -1 && (fds[idx].revents & POLLIN)) 4032 if (ret > 0 && idx != -1 && (fds[idx].revents & POLLIN))
4020 { 4033 {
4021 channel_read(channel, part, "channel_poll_check"); 4034 channel_read(channel, part, "channel_poll_check");
4022 --ret; 4035 --ret;
4023 } 4036 }
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 }
4024 } 4043 }
4025 4044
4026 in_part = &channel->ch_part[PART_IN]; 4045 in_part = &channel->ch_part[PART_IN];
4027 idx = in_part->ch_poll_idx; 4046 idx = in_part->ch_poll_idx;
4028 if (ret > 0 && idx != -1 && (fds[idx].revents & POLLOUT)) 4047 if (ret > 0 && idx != -1 && (fds[idx].revents & POLLOUT))
4035 return ret; 4054 return ret;
4036 } 4055 }
4037 # endif /* UNIX && !HAVE_SELECT */ 4056 # endif /* UNIX && !HAVE_SELECT */
4038 4057
4039 # if (!defined(WIN32) && defined(HAVE_SELECT)) || defined(PROTO) 4058 # if (!defined(WIN32) && defined(HAVE_SELECT)) || defined(PROTO)
4059
4040 /* 4060 /*
4041 * The "fd_set" type is hidden to avoid problems with the function proto. 4061 * The "fd_set" type is hidden to avoid problems with the function proto.
4042 */ 4062 */
4043 int 4063 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)
4045 { 4070 {
4046 int maxfd = maxfd_in; 4071 int maxfd = maxfd_in;
4047 channel_T *channel; 4072 channel_T *channel;
4048 fd_set *rfds = rfds_in; 4073 fd_set *rfds = rfds_in;
4049 fd_set *wfds = wfds_in; 4074 fd_set *wfds = wfds_in;
4055 { 4080 {
4056 sock_T fd = channel->ch_part[part].ch_fd; 4081 sock_T fd = channel->ch_part[part].ch_fd;
4057 4082
4058 if (fd != INVALID_FD) 4083 if (fd != INVALID_FD)
4059 { 4084 {
4060 FD_SET((int)fd, rfds); 4085 if (channel->ch_keep_open)
4061 if (maxfd < (int)fd) 4086 {
4062 maxfd = (int)fd; 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 }
4063 } 4104 }
4064 } 4105 }
4065 } 4106 }
4066 4107
4067 maxfd = channel_fill_wfds(maxfd, wfds); 4108 maxfd = channel_fill_wfds(maxfd, wfds);
4091 if (ret > 0 && fd != INVALID_FD && FD_ISSET(fd, rfds)) 4132 if (ret > 0 && fd != INVALID_FD && FD_ISSET(fd, rfds))
4092 { 4133 {
4093 channel_read(channel, part, "channel_select_check"); 4134 channel_read(channel, part, "channel_select_check");
4094 FD_CLR(fd, rfds); 4135 FD_CLR(fd, rfds);
4095 --ret; 4136 --ret;
4137 }
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");
4096 } 4142 }
4097 } 4143 }
4098 4144
4099 in_part = &channel->ch_part[PART_IN]; 4145 in_part = &channel->ch_part[PART_IN];
4100 if (ret > 0 && in_part->ch_fd != INVALID_FD 4146 if (ret > 0 && in_part->ch_fd != INVALID_FD