Patch 7.4.1319 (after 7.4.1318)
Problem:    Tests fail on MS-Windows and on Unix with GUI.
Solution:   Fix unregistering.
Files:      src/structs.h, src/channel.c, src/os_unix.c, src/os_win32.c,
            src/proto/channel.pro


*** ../vim-7.4.1318/src/structs.h       2016-02-14 19:13:37.314808670 +0100
--- src/structs.h       2016-02-14 21:48:58.429255434 +0100
***************
*** 1301,1308 ****
      MODE_JS
  } ch_mode_T;
  
! /* Ordering matters: IN is last, only SOCK/OUT/ERR are polled */
! 
  #define CHAN_SOCK   0
  #define CH_SOCK           ch_pfd[CHAN_SOCK].ch_fd
  
--- 1301,1308 ----
      MODE_JS
  } ch_mode_T;
  
! /* Ordering matters, it is used in for loops: IN is last, only SOCK/OUT/ERR
!  * are polled. */
  #define CHAN_SOCK   0
  #define CH_SOCK           ch_pfd[CHAN_SOCK].ch_fd
  
***************
*** 1342,1348 ****
  
      int               ch_id;          /* ID of the channel */
  
!     chan_fd_T ch_pfd[4];      /* info for socket, in, out and err */
  
      readq_T   ch_head;        /* dummy node, header for circular queue */
  
--- 1342,1348 ----
  
      int               ch_id;          /* ID of the channel */
  
!     chan_fd_T ch_pfd[4];      /* info for socket, out, err and in */
  
      readq_T   ch_head;        /* dummy node, header for circular queue */
  
***************
*** 1351,1356 ****
--- 1351,1357 ----
                                 * the other side has exited, only mention the
                                 * first error until the connection works
                                 * again. */
+ 
      void      (*ch_close_cb)(void); /* callback for when channel is closed */
  
      int               ch_block_id;    /* ID that channel_read_json_block() is
*** ../vim-7.4.1318/src/channel.c       2016-02-14 19:13:37.318808628 +0100
--- src/channel.c       2016-02-14 22:52:14.204212504 +0100
***************
*** 339,346 ****
       * is input on the editor connection socket. */
      if (channel->ch_pfd[which].ch_inputHandler == 0)
        channel->ch_pfd[which].ch_inputHandler = gdk_input_add(
!               (gint)channel->ch_pfd[which].ch_fd, (GdkInputCondition)
!               ((int)GDK_INPUT_READ + (int)GDK_INPUT_EXCEPTION),
                messageFromNetbeans,
                (gpointer)(long)channel->ch_id);
  #  else
--- 339,347 ----
       * is input on the editor connection socket. */
      if (channel->ch_pfd[which].ch_inputHandler == 0)
        channel->ch_pfd[which].ch_inputHandler = gdk_input_add(
!               (gint)channel->ch_pfd[which].ch_fd,
!               (GdkInputCondition)
!                            ((int)GDK_INPUT_READ + (int)GDK_INPUT_EXCEPTION),
                messageFromNetbeans,
                (gpointer)(long)channel->ch_id);
  #  else
***************
*** 362,373 ****
      if (!CH_HAS_GUI)
        return;
  
!     if (channel->ch_pfd[CHAN_SOCK].ch_fd >= 0)
        channel_gui_register_one(channel, CHAN_SOCK);
  # ifdef CHANNEL_PIPES
!     if (channel->ch_pfd[CHAN_OUT].ch_fd >= 0)
        channel_gui_register_one(channel, CHAN_OUT);
!     if (channel->ch_pfd[CHAN_ERR].ch_fd >= 0)
        channel_gui_register_one(channel, CHAN_ERR);
  # endif
  }
--- 363,374 ----
      if (!CH_HAS_GUI)
        return;
  
!     if (channel->CH_SOCK >= 0)
        channel_gui_register_one(channel, CHAN_SOCK);
  # ifdef CHANNEL_PIPES
!     if (channel->CH_OUT >= 0)
        channel_gui_register_one(channel, CHAN_OUT);
!     if (channel->CH_ERR >= 0)
        channel_gui_register_one(channel, CHAN_ERR);
  # endif
  }
***************
*** 386,429 ****
  }
  
      static void
! channel_gui_unregister_one(channel_T *channel, int which)
  {
! # ifdef FEAT_GUI_X11
!     if (channel->ch_pfd[which].ch_inputHandler != (XtInputId)NULL)
      {
!       XtRemoveInput(channel->ch_pfd[which].ch_inputHandler);
!       channel->ch_pfd[which].ch_inputHandler = (XtInputId)NULL;
!     }
  # else
  #  ifdef FEAT_GUI_GTK
!     if (channel->ch_pfd[which].ch_inputHandler != 0)
!     {
!       gdk_input_remove(channel->ch_pfd[which].ch_inputHandler);
!       channel->ch_pfd[which].ch_inputHandler = 0;
!     }
  #  else
  #   ifdef FEAT_GUI_W32
!     if (channel->ch_pfd[which].ch_inputHandler == 0)
!     {
!       WSAAsyncSelect(channel->ch_pfd[which].ch_fd, s_hwnd, 0, 0);
!       channel->ch_pfd[which].ch_inputHandler = -1;
!     }
  #   endif
  #  endif
  # endif
! }
! 
!     static void
! channel_gui_unregister(channel_T *channel)
! {
!     if (channel->ch_pfd[CHAN_SOCK].ch_fd >= 0)
!       channel_gui_unregister_one(channel, CHAN_SOCK);
! # ifdef CHANNEL_PIPES
!     if (channel->ch_pfd[CHAN_OUT].ch_fd >= 0)
!       channel_gui_unregister_one(channel, CHAN_OUT);
!     if (channel->ch_pfd[CHAN_ERR].ch_fd >= 0)
!       channel_gui_unregister_one(channel, CHAN_ERR);
! # endif
  }
  
  #endif
--- 387,426 ----
  }
  
      static void
! channel_gui_unregister(channel_T *channel)
  {
!     int           which;
! 
! #ifdef CHANNEL_PIPES
!     for (which = CHAN_SOCK; which < CHAN_IN; ++which)
! #else
!     which = CHAN_SOCK;
! #endif
      {
! # ifdef FEAT_GUI_X11
!       if (channel->ch_pfd[which].ch_inputHandler != (XtInputId)NULL)
!       {
!           XtRemoveInput(channel->ch_pfd[which].ch_inputHandler);
!           channel->ch_pfd[which].ch_inputHandler = (XtInputId)NULL;
!       }
  # else
  #  ifdef FEAT_GUI_GTK
!       if (channel->ch_pfd[which].ch_inputHandler != 0)
!       {
!           gdk_input_remove(channel->ch_pfd[which].ch_inputHandler);
!           channel->ch_pfd[which].ch_inputHandler = 0;
!       }
  #  else
  #   ifdef FEAT_GUI_W32
!       if (channel->ch_pfd[which].ch_inputHandler == 0)
!       {
!           WSAAsyncSelect(channel->ch_pfd[which].ch_fd, s_hwnd, 0, 0);
!           channel->ch_pfd[which].ch_inputHandler = -1;
!       }
  #   endif
  #  endif
  # endif
!     }
  }
  
  #endif
***************
*** 1192,1207 ****
  {
      ch_log(channel, "Closing channel");
  
      if (channel->CH_SOCK >= 0)
      {
        sock_close(channel->CH_SOCK);
        channel->CH_SOCK = -1;
-       channel->ch_close_cb = NULL;
- #ifdef FEAT_GUI
-       channel_gui_unregister(channel);
- #endif
-       vim_free(channel->ch_callback);
-       channel->ch_callback = NULL;
      }
  #if defined(CHANNEL_PIPES)
      if (channel->CH_IN >= 0)
--- 1189,1202 ----
  {
      ch_log(channel, "Closing channel");
  
+ #ifdef FEAT_GUI
+     channel_gui_unregister(channel);
+ #endif
+ 
      if (channel->CH_SOCK >= 0)
      {
        sock_close(channel->CH_SOCK);
        channel->CH_SOCK = -1;
      }
  #if defined(CHANNEL_PIPES)
      if (channel->CH_IN >= 0)
***************
*** 1220,1225 ****
--- 1215,1224 ----
        channel->CH_ERR = -1;
      }
  #endif
+ 
+     channel->ch_close_cb = NULL;
+     vim_free(channel->ch_callback);
+     channel->ch_callback = NULL;
      channel_clear(channel);
  }
  
***************
*** 1383,1389 ****
  
  /*
   * Get the file descriptor to read from, either the socket or stdout.
!  * TODO: never gets stderr.
   */
      static int
  get_read_fd(channel_T *channel)
--- 1382,1388 ----
  
  /*
   * Get the file descriptor to read from, either the socket or stdout.
!  * TODO: should have a way to read stderr.
   */
      static int
  get_read_fd(channel_T *channel)
***************
*** 1400,1406 ****
  
  /*
   * Read from channel "channel" for as long as there is something to read.
!  * "which" is CHAN_SOCK, CHAN_OUT or CHAN_ERR.  When -1 guess.
   * The data is put in the read queue.
   */
      void
--- 1399,1406 ----
  
  /*
   * Read from channel "channel" for as long as there is something to read.
!  * "which" is CHAN_SOCK, CHAN_OUT or CHAN_ERR.  When -1 use CHAN_SOCK or
!  * CHAN_OUT, the one that is open.
   * The data is put in the read queue.
   */
      void
***************
*** 1475,1493 ****
        ch_errors(channel, "%s(): Cannot read\n", func);
        channel_save(channel, (char_u *)DETACH_MSG, (int)STRLEN(DETACH_MSG));
  
!       if (use_socket)
!       {
!           channel_close(channel);
!           if (channel->ch_close_cb != NULL)
!               (*channel->ch_close_cb)();
!       }
! #if defined(CHANNEL_PIPES)
!       else
!       {
!           close(fd);
!           channel->CH_OUT = -1;
!       }
! #endif
  
        if (len < 0)
        {
--- 1475,1486 ----
        ch_errors(channel, "%s(): Cannot read\n", func);
        channel_save(channel, (char_u *)DETACH_MSG, (int)STRLEN(DETACH_MSG));
  
!       /* TODO: When reading from stdout is not possible, should we try to
!        * keep stdin and stderr open?  Probably not, assume the other side
!        * has died. */
!       channel_close(channel);
!       if (channel->ch_close_cb != NULL)
!           (*channel->ch_close_cb)();
  
        if (len < 0)
        {
***************
*** 1587,1592 ****
--- 1580,1586 ----
      if (fd >= 0)
        for (channel = first_channel; channel != NULL;
                                                   channel = channel->ch_next)
+       {
  #  ifdef CHANNEL_PIPES
            for (i = CHAN_SOCK; i < CHAN_IN; ++i)
  #  else
***************
*** 1595,1602 ****
                if (channel->ch_pfd[i].ch_fd == fd)
                {
                    *whichp = i;
!                   return channel
                }
      return NULL;
  }
  # endif
--- 1589,1597 ----
                if (channel->ch_pfd[i].ch_fd == fd)
                {
                    *whichp = i;
!                   return channel;
                }
+       }
      return NULL;
  }
  # endif
***************
*** 1638,1644 ****
      {
        ch_log_lead("SEND ", channel);
        fprintf(log_fd, "'");
!       ignored = fwrite(buf, len, 1, log_fd);
        fprintf(log_fd, "'\n");
        fflush(log_fd);
      }
--- 1633,1639 ----
      {
        ch_log_lead("SEND ", channel);
        fprintf(log_fd, "'");
!       ignored = (int)fwrite(buf, len, 1, log_fd);
        fprintf(log_fd, "'\n");
        fflush(log_fd);
      }
***************
*** 1677,1687 ****
--- 1672,1684 ----
      int               which;
  
      for (channel = first_channel; channel != NULL; channel = channel->ch_next)
+     {
  #  ifdef CHANNEL_PIPES
        for (which = CHAN_SOCK; which < CHAN_IN; ++which)
  #  else
        which = CHAN_SOCK;
  #  endif
+       {
            if (channel->ch_pfd[which].ch_fd >= 0)
            {
                channel->ch_pfd[which].ch_poll_idx = nfd;
***************
*** 1691,1696 ****
--- 1688,1695 ----
            }
            else
                channel->ch_pfd[which].ch_poll_idx = -1;
+       }
+     }
  
      return nfd;
  }
***************
*** 1707,1714 ****
      int               which;
  
      for (channel = first_channel; channel != NULL; channel = channel->ch_next)
  #  ifdef CHANNEL_PIPES
!       for (which = CHAN_SOCK; which < CHAN_IN; ++which)
  #  else
        which = CHAN_SOCK;
  #  endif
--- 1706,1714 ----
      int               which;
  
      for (channel = first_channel; channel != NULL; channel = channel->ch_next)
+     {
  #  ifdef CHANNEL_PIPES
!       for (which = CHAN_SOCK; which < CH_IN; ++which)
  #  else
        which = CHAN_SOCK;
  #  endif
***************
*** 1721,1726 ****
--- 1721,1727 ----
                --ret;
            }
        }
+     }
  
      return ret;
  }
***************
*** 1739,1744 ****
--- 1740,1746 ----
      int               which;
  
      for (channel = first_channel; channel != NULL; channel = channel->ch_next)
+     {
  #  ifdef CHANNEL_PIPES
        for (which = CHAN_SOCK; which < CHAN_IN; ++which)
  #  else
***************
*** 1754,1759 ****
--- 1756,1762 ----
                    maxfd = fd;
            }
        }
+     }
  
      return maxfd;
  }
***************
*** 1770,1775 ****
--- 1773,1779 ----
      int               which;
  
      for (channel = first_channel; channel != NULL; channel = channel->ch_next)
+     {
  #  ifdef CHANNEL_PIPES
        for (which = CHAN_SOCK; which < CHAN_IN; ++which)
  #  else
***************
*** 1784,1789 ****
--- 1788,1794 ----
                --ret;
            }
        }
+     }
  
      return ret;
  }
*** ../vim-7.4.1318/src/os_unix.c       2016-02-14 19:13:37.322808585 +0100
--- src/os_unix.c       2016-02-14 22:10:26.847671765 +0100
***************
*** 5043,5049 ****
      int               fd_in[2];       /* for stdin */
      int               fd_out[2];      /* for stdout */
      int               fd_err[2];      /* for stderr */
!     channel_T *channel;
  
      /* default is to fail */
      job->jv_status = JOB_FAILED;
--- 5043,5049 ----
      int               fd_in[2];       /* for stdin */
      int               fd_out[2];      /* for stdout */
      int               fd_err[2];      /* for stderr */
!     channel_T *channel = NULL;
  
      /* default is to fail */
      job->jv_status = JOB_FAILED;
*** ../vim-7.4.1318/src/os_win32.c      2016-02-14 19:13:37.322808585 +0100
--- src/os_win32.c      2016-02-14 22:58:57.824939391 +0100
***************
*** 5039,5051 ****
      STARTUPINFO               si;
      PROCESS_INFORMATION       pi;
      HANDLE            jo;
! #ifdef FEAT_CHANNEL
!     channel_T *channel;
  
      channel = add_channel();
      if (channel == NULL)
        return;
! #endif
  
      jo = CreateJobObject(NULL, NULL);
      if (jo == NULL)
--- 5039,5051 ----
      STARTUPINFO               si;
      PROCESS_INFORMATION       pi;
      HANDLE            jo;
! # ifdef FEAT_CHANNEL
!     channel_T         *channel;
  
      channel = add_channel();
      if (channel == NULL)
        return;
! # endif
  
      jo = CreateJobObject(NULL, NULL);
      if (jo == NULL)
***************
*** 5085,5108 ****
      job->jv_job_object = jo;
      job->jv_status = JOB_STARTED;
  
! #ifdef FEAT_CHANNEL
! # if 0
      /* TODO: connect stdin/stdout/stderr */
      job->jv_channel = channel;
      channel_set_pipes(channel, fd_in[1], fd_out[0], fd_err[0]);
      channel_set_job(channel, job);
  
! #  ifdef FEAT_GUI
       channel_gui_register(channel);
  #  endif
  # endif
- #endif
      return;
  
  failed:
! #ifdef FEAT_CHANNEL
      channel_free(channel);
! #endif
  }
  
      char *
--- 5085,5108 ----
      job->jv_job_object = jo;
      job->jv_status = JOB_STARTED;
  
! # ifdef FEAT_CHANNEL
! #  if 0
      /* TODO: connect stdin/stdout/stderr */
      job->jv_channel = channel;
      channel_set_pipes(channel, fd_in[1], fd_out[0], fd_err[0]);
      channel_set_job(channel, job);
  
! #   ifdef FEAT_GUI
       channel_gui_register(channel);
+ #   endif
  #  endif
  # endif
      return;
  
  failed:
! # ifdef FEAT_CHANNEL
      channel_free(channel);
! # endif
  }
  
      char *
*** ../vim-7.4.1318/src/proto/channel.pro       2016-02-14 19:13:37.326808543 
+0100
--- src/proto/channel.pro       2016-02-14 22:46:13.605009553 +0100
***************
*** 22,31 ****
  void channel_clear(channel_T *channel);
  void channel_free_all(void);
  int channel_get_id(void);
! void channel_read(channel_T *channel, int what, char *func);
  char_u *channel_read_block(channel_T *channel);
  int channel_read_json_block(channel_T *channel, int id, typval_T **rettv);
! channel_T *channel_fd2channel(sock_T fd, int *what);
  int channel_send(channel_T *channel, char_u *buf, char *fun);
  int channel_poll_setup(int nfd_in, void *fds_in);
  int channel_poll_check(int ret_in, void *fds_in);
--- 22,31 ----
  void channel_clear(channel_T *channel);
  void channel_free_all(void);
  int channel_get_id(void);
! void channel_read(channel_T *channel, int which, char *func);
  char_u *channel_read_block(channel_T *channel);
  int channel_read_json_block(channel_T *channel, int id, typval_T **rettv);
! channel_T *channel_fd2channel(sock_T fd, int *whichp);
  int channel_send(channel_T *channel, char_u *buf, char *fun);
  int channel_poll_setup(int nfd_in, void *fds_in);
  int channel_poll_check(int ret_in, void *fds_in);
*** ../vim-7.4.1318/src/version.c       2016-02-14 19:13:37.326808543 +0100
--- src/version.c       2016-02-14 20:45:01.705422355 +0100
***************
*** 749,750 ****
--- 749,752 ----
  {   /* Add new patch number below this line */
+ /**/
+     1319,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
255. You work for a newspaper and your editor asks you to write an
     article about Internet addiction...in the "first person."

 /// Bram Moolenaar -- [email protected] -- 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 [email protected].
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui