On Mon, Feb 22, 2016 at 1:19 AM, Bram Moolenaar <[email protected]> wrote:

>
> Yukihiro Nakadaira wrote:
>
> > test_channel.vim fails with Win32 CUI Vim.
> >
> > What the following patch fix is
> > 1. Vim sleep 5 msec even when timeout=0.
> > 2. channel_handle_events() closes channel when there is no input.
> > 3. ":sleep" command does not read channel (I am not sure where is the
> right
> >    place to call channel_handle_events()).
>
> Thanks!
>
> For Unix checking for events happens in mch_breakcheck().  And any other
> place where RealWaitForChar() is called.
>
> I hesitate to add channel_handle_events() in mch_breakcheck, it might be
> too slow.  Perhaps it's better to put it inside parse_queued_messages().
> That sort of makes sense.  And we can remove the other calls to
> channel_handle_events() since parse_queued_messages() is called there
> already.  They were actually in the wrong order.
>
> Let me make that change.  Please check if it works.
>

It works fine.


>
> Did you look at the problem that ch_read() doesn't timeout for Win32?
> It's disabled in the test for now.
>

To implement timeout, we need to use select() instead of WSAAsyncSelect().
Patch is attached.  With this patch, Vim checks channel each 100
milliseconds
while waiting window message.

-- 
Yukihiro Nakadaira - [email protected]

-- 
-- 
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.
diff --git a/src/channel.c b/src/channel.c
index aa97088..5afc088 100644
--- a/src/channel.c
+++ b/src/channel.c
@@ -52,10 +52,6 @@
 # define fd_close(sd) close(sd)
 #endif
 
-#ifdef FEAT_GUI_W32
-extern HWND s_hwnd;                    /* Gvim's Window handle */
-#endif
-
 #ifdef WIN32
     static int
 fd_read(sock_T fd, char *buf, size_t len)
@@ -296,9 +292,6 @@ add_channel(void)
 #ifdef FEAT_GUI_GTK
        channel->ch_part[part].ch_inputHandler = 0;
 #endif
-#ifdef FEAT_GUI_W32
-       channel->ch_part[part].ch_inputHandler = -1;
-#endif
        channel->ch_part[part].ch_timeout = 2000;
     }
 
@@ -394,15 +387,6 @@ channel_gui_register_one(channel_T *channel, int part)
                             ((int)GDK_INPUT_READ + (int)GDK_INPUT_EXCEPTION),
                messageFromNetbeans,
                (gpointer)(long)channel->ch_part[part].ch_fd);
-#  else
-#   ifdef FEAT_GUI_W32
-    /* Tell Windows we are interested in receiving message when there
-     * is input on the editor connection socket.  */
-    if (channel->ch_part[part].ch_inputHandler == -1)
-       channel->ch_part[part].ch_inputHandler = WSAAsyncSelect(
-               channel->ch_part[part].ch_fd,
-               s_hwnd, WM_NETBEANS, FD_READ);
-#   endif
 #  endif
 # endif
 }
@@ -460,14 +444,6 @@ channel_gui_unregister(channel_T *channel)
            gdk_input_remove(channel->ch_part[part].ch_inputHandler);
            channel->ch_part[part].ch_inputHandler = 0;
        }
-#  else
-#   ifdef FEAT_GUI_W32
-       if (channel->ch_part[part].ch_inputHandler == 0)
-       {
-           WSAAsyncSelect(channel->ch_part[part].ch_fd, s_hwnd, 0, 0);
-           channel->ch_part[part].ch_inputHandler = -1;
-       }
-#   endif
 #  endif
 # endif
     }
@@ -1562,7 +1538,6 @@ channel_free_all(void)
 /*
  * Check for reading from "fd" with "timeout" msec.
  * Return FAIL when there is nothing to read.
- * Always returns OK for FEAT_GUI_W32.
  */
     static int
 channel_wait(channel_T *channel, sock_T fd, int timeout)
@@ -1594,12 +1569,7 @@ channel_wait(channel_T *channel, sock_T fd, int timeout)
     else
 #endif
     {
-#if defined(FEAT_GUI_W32)
-       /* Can't check socket for Win32 GUI, always return OK. */
-       ch_log(channel, "Can't check, assuming there is something to read");
-       return OK;
-#else
-# if defined(HAVE_SELECT)
+#if defined(HAVE_SELECT)
        struct timeval  tval;
        fd_set          rfds;
        int                     ret;
@@ -1611,23 +1581,22 @@ channel_wait(channel_T *channel, sock_T fd, int timeout)
        for (;;)
        {
            ret = select((int)fd + 1, &rfds, NULL, NULL, &tval);
-#  ifdef EINTR
+# ifdef EINTR
            SOCK_ERRNO;
            if (ret == -1 && errno == EINTR)
                continue;
-#  endif
+# endif
            if (ret > 0)
                return OK;
            break;
        }
-# else
+#else
        struct pollfd   fds;
 
        fds.fd = fd;
        fds.events = POLLIN;
        if (poll(&fds, 1, timeout) > 0)
            return OK;
-# endif
 #endif
     }
     ch_log(channel, "Nothing to read");
@@ -1695,16 +1664,6 @@ channel_read(channel_T *channel, int part, char *func)
        if (len < MAXMSGSIZE)
            break;      /* did read everything that's available */
     }
-#ifdef FEAT_GUI_W32
-    if (use_socket && len == SOCKET_ERROR)
-    {
-       /* For Win32 GUI channel_wait() always returns OK and we handle the
-        * situation that there is nothing to read here.
-        * TODO: how about a timeout? */
-       if (WSAGetLastError() == WSAEWOULDBLOCK)
-           return;
-    }
-#endif
 
     /* Reading a socket disconnection (readlen == 0), or a socket error.
      * TODO: call error callback. */
@@ -1899,17 +1858,12 @@ channel_handle_events(void)
 
     for (channel = first_channel; channel != NULL; channel = channel->ch_next)
     {
-#  ifdef FEAT_GUI_W32
-       /* only check the pipes */
-       for (part = PART_OUT; part <= PART_ERR; ++part)
-#  else
-#   ifdef CHANNEL_PIPES
+#  ifdef CHANNEL_PIPES
        /* check the socket and pipes */
        for (part = PART_SOCK; part <= PART_ERR; ++part)
-#   else
+#  else
        /* only check the socket */
        part = PART_SOCK;
-#   endif
 #  endif
        {
            fd = channel->ch_part[part].ch_fd;
diff --git a/src/gui_w32.c b/src/gui_w32.c
index 3a64691..edfe24e 100644
--- a/src/gui_w32.c
+++ b/src/gui_w32.c
@@ -1927,24 +1927,6 @@ process_message(void)
     }
 #endif
 
-#ifdef FEAT_CHANNEL
-    if (msg.message == WM_NETBEANS)
-    {
-       int         part;
-       channel_T   *channel = channel_fd2channel((sock_T)msg.wParam, &part);
-
-       if (channel != NULL)
-       {
-           /* Disable error messages, they can mess up the display and throw
-            * an exception. */
-           ++emsg_off;
-           channel_read(channel, part, "process_message");
-           --emsg_off;
-       }
-       return;
-    }
-#endif
-
 #ifdef FEAT_SNIFF
     if (sniff_request_waiting && want_sniff_request)
     {
@@ -2245,7 +2227,18 @@ gui_mch_wait_for_chars(int wtime)
        }
 
 #ifdef MESSAGE_QUEUE
-       parse_queued_messages();
+       /* Check channel while waiting message. */
+       for (;;)
+       {
+           MSG msg;
+
+           parse_queued_messages();
+
+           if (pPeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)
+               || MsgWaitForMultipleObjects(0, NULL, FALSE, 100, QS_ALLEVENTS)
+                                                               != WAIT_TIMEOUT)
+               break;
+       }
 #endif
 
        /*
diff --git a/src/os_win32.c b/src/os_win32.c
index 0470450..e93e6d0 100644
--- a/src/os_win32.c
+++ b/src/os_win32.c
@@ -1492,6 +1492,11 @@ WaitForChar(long msec)
        {
            DWORD dwWaitTime = dwEndTime - dwNow;
 
+#ifdef FEAT_CHANNEL
+           /* Check channel while waiting input. */
+           if (dwWaitTime > 100)
+               dwWaitTime = 100;
+#endif
 #ifdef FEAT_MZSCHEME
            if (mzthreads_allowed() && p_mzq > 0
                                    && (msec < 0 || (long)dwWaitTime > p_mzq))
diff --git a/src/structs.h b/src/structs.h
index e1720ce..b4970ee 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -1336,9 +1336,6 @@ typedef struct {
 #ifdef FEAT_GUI_GTK
     gint       ch_inputHandler; /* Cookie for input */
 #endif
-#ifdef WIN32
-    int                ch_inputHandler; /* ret.value of WSAAsyncSelect() */
-#endif
 
     ch_mode_T  ch_mode;
     int                ch_timeout;     /* request timeout in msec */
diff --git a/src/testdir/test_channel.vim b/src/testdir/test_channel.vim
index 2b4b189..0f7534a 100644
--- a/src/testdir/test_channel.vim
+++ b/src/testdir/test_channel.vim
@@ -131,10 +131,10 @@ func s:communicate(port)
     call assert_false(1, 's:responseHandle was not set')
   else
     call assert_equal(handle, s:responseHandle)
+    unlet s:responseHandle
   endif
   call assert_equal('got it', s:responseMsg)
 
-  unlet s:responseHandle
   let s:responseMsg = ''
   call ch_sendexpr(handle, 'hello!', {'callback': 
function('s:RequestHandler')})
   sleep 10m
@@ -142,6 +142,7 @@ func s:communicate(port)
     call assert_false(1, 's:responseHandle was not set')
   else
     call assert_equal(handle, s:responseHandle)
+    unlet s:responseHandle
   endif
   call assert_equal('got it', s:responseMsg)
 
@@ -186,15 +187,12 @@ func s:communicate(port)
   call assert_equal('ok', ch_sendexpr(handle, 'empty-request'))
 
   " Reading while there is nothing available.
-  " TODO: make this work for MS-Windows
-  if has('unix')
-    call assert_equal(v:none, ch_read(handle, {'timeout': 0}))
-    let start = reltime()
-    call assert_equal(v:none, ch_read(handle, {'timeout': 333}))
-    let elapsed = reltime(start)
-    call assert_true(reltimefloat(elapsed) > 0.3)
-    call assert_true(reltimefloat(elapsed) < 0.6)
-  endif
+  call assert_equal(v:none, ch_read(handle, {'timeout': 0}))
+  let start = reltime()
+  call assert_equal(v:none, ch_read(handle, {'timeout': 333}))
+  let elapsed = reltime(start)
+  call assert_true(reltimefloat(elapsed) > 0.3)
+  call assert_true(reltimefloat(elapsed) < 0.6)
 
   " Send without waiting for a response, then wait for a response.
   call ch_sendexpr(handle, 'wait a bit',  {'callback': 0})
diff --git a/src/vim.h b/src/vim.h
index 7a7a758..5567faf 100644
--- a/src/vim.h
+++ b/src/vim.h
@@ -1917,10 +1917,6 @@ typedef int sock_T;
 #  ifdef FEAT_OLE
 #   define WM_OLE (WM_APP+0)
 #  endif
-#  ifdef FEAT_CHANNEL
-    /* message for channel socket event */
-#   define WM_NETBEANS (WM_APP+1)
-#  endif
 # endif
 
 /* Info about selected text */

Raspunde prin e-mail lui