Mercurial > vim
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 |