forked from aniani/vim
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().
This commit is contained in:
@@ -3960,6 +3960,8 @@ ch_raw_common(typval_T *argvars, typval_T *rettv, int eval)
|
||||
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,7 +3969,7 @@ ch_raw_common(typval_T *argvars, typval_T *rettv, int eval)
|
||||
* The type of "fds" is hidden to avoid problems with the function proto.
|
||||
*/
|
||||
int
|
||||
channel_poll_setup(int nfd_in, void *fds_in)
|
||||
channel_poll_setup(int nfd_in, void *fds_in, int *towait)
|
||||
{
|
||||
int nfd = nfd_in;
|
||||
channel_T *channel;
|
||||
@@ -3982,10 +3984,21 @@ channel_poll_setup(int nfd_in, void *fds_in)
|
||||
|
||||
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++;
|
||||
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,6 +4034,12 @@ channel_poll_check(int ret_in, void *fds_in)
|
||||
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,11 +4056,17 @@ channel_poll_check(int ret_in, void *fds_in)
|
||||
# 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)
|
||||
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,9 +4082,25 @@ channel_select_setup(int maxfd_in, void *rfds_in, void *wfds_in)
|
||||
|
||||
if (fd != INVALID_FD)
|
||||
{
|
||||
FD_SET((int)fd, rfds);
|
||||
if (maxfd < (int)fd)
|
||||
maxfd = (int)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,6 +4135,11 @@ channel_select_check(int ret_in, void *rfds_in, void *wfds_in)
|
||||
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];
|
||||
|
Reference in New Issue
Block a user