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 -- b...@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    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui