0
0
mirror of https://github.com/vim/vim.git synced 2025-10-01 04:54:07 -04:00

patch 7.4.1404

Problem:    ch_read() doesn't time out on MS-Windows.
Solution:   Instead of WM_NETBEANS use select(). (Yukihiro Nakadaira)
This commit is contained in:
Bram Moolenaar
2016-02-23 19:34:01 +01:00
parent 0106e3d0bf
commit 9186a27622
7 changed files with 33 additions and 88 deletions

View File

@@ -52,10 +52,6 @@
# define fd_close(sd) close(sd) # define fd_close(sd) close(sd)
#endif #endif
#ifdef FEAT_GUI_W32
extern HWND s_hwnd; /* Gvim's Window handle */
#endif
#ifdef WIN32 #ifdef WIN32
static int static int
fd_read(sock_T fd, char *buf, size_t len) fd_read(sock_T fd, char *buf, size_t len)
@@ -295,9 +291,6 @@ add_channel(void)
#endif #endif
#ifdef FEAT_GUI_GTK #ifdef FEAT_GUI_GTK
channel->ch_part[part].ch_inputHandler = 0; channel->ch_part[part].ch_inputHandler = 0;
#endif
#ifdef FEAT_GUI_W32
channel->ch_part[part].ch_inputHandler = -1;
#endif #endif
channel->ch_part[part].ch_timeout = 2000; channel->ch_part[part].ch_timeout = 2000;
} }
@@ -421,15 +414,6 @@ channel_gui_register_one(channel_T *channel, int part)
messageFromNetbeans, messageFromNetbeans,
(gpointer)(long)channel->ch_part[part].ch_fd); (gpointer)(long)channel->ch_part[part].ch_fd);
# endif # endif
# 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
# endif # endif
} }
@@ -491,14 +475,6 @@ channel_gui_unregister(channel_T *channel)
# endif # endif
channel->ch_part[part].ch_inputHandler = 0; 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
# endif # endif
} }
@@ -1630,7 +1606,6 @@ channel_free_all(void)
/* /*
* Check for reading from "fd" with "timeout" msec. * Check for reading from "fd" with "timeout" msec.
* Return FAIL when there is nothing to read. * Return FAIL when there is nothing to read.
* Always returns OK for FEAT_GUI_W32.
*/ */
static int static int
channel_wait(channel_T *channel, sock_T fd, int timeout) channel_wait(channel_T *channel, sock_T fd, int timeout)
@@ -1662,11 +1637,6 @@ channel_wait(channel_T *channel, sock_T fd, int timeout)
else else
#endif #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; struct timeval tval;
fd_set rfds; fd_set rfds;
@@ -1695,7 +1665,6 @@ channel_wait(channel_T *channel, sock_T fd, int timeout)
fds.events = POLLIN; fds.events = POLLIN;
if (poll(&fds, 1, timeout) > 0) if (poll(&fds, 1, timeout) > 0)
return OK; return OK;
# endif
#endif #endif
} }
ch_log(channel, "Nothing to read"); ch_log(channel, "Nothing to read");
@@ -1764,16 +1733,6 @@ channel_read(channel_T *channel, int part, char *func)
if (len < MAXMSGSIZE) if (len < MAXMSGSIZE)
break; /* did read everything that's available */ 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 disconnection (readlen == 0), or an error. /* Reading a disconnection (readlen == 0), or an error.
* TODO: call error callback. */ * TODO: call error callback. */
@@ -1970,17 +1929,12 @@ channel_handle_events(void)
for (channel = first_channel; channel != NULL; channel = channel->ch_next) 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 */ /* check the socket and pipes */
for (part = PART_SOCK; part <= PART_ERR; ++part) for (part = PART_SOCK; part <= PART_ERR; ++part)
# else # else
/* only check the socket */ /* only check the socket */
part = PART_SOCK; part = PART_SOCK;
# endif
# endif # endif
{ {
fd = channel->ch_part[part].ch_fd; fd = channel->ch_part[part].ch_fd;

View File

@@ -1927,24 +1927,6 @@ process_message(void)
} }
#endif #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 #ifdef FEAT_SNIFF
if (sniff_request_waiting && want_sniff_request) if (sniff_request_waiting && want_sniff_request)
{ {
@@ -2245,7 +2227,18 @@ gui_mch_wait_for_chars(int wtime)
} }
#ifdef MESSAGE_QUEUE #ifdef MESSAGE_QUEUE
/* Check channel while waiting message. */
for (;;)
{
MSG msg;
parse_queued_messages(); parse_queued_messages();
if (pPeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)
|| MsgWaitForMultipleObjects(0, NULL, FALSE, 100, QS_ALLEVENTS)
!= WAIT_TIMEOUT)
break;
}
#endif #endif
/* /*

View File

@@ -1492,6 +1492,11 @@ WaitForChar(long msec)
{ {
DWORD dwWaitTime = dwEndTime - dwNow; DWORD dwWaitTime = dwEndTime - dwNow;
#ifdef FEAT_CHANNEL
/* Check channel while waiting input. */
if (dwWaitTime > 100)
dwWaitTime = 100;
#endif
#ifdef FEAT_MZSCHEME #ifdef FEAT_MZSCHEME
if (mzthreads_allowed() && p_mzq > 0 if (mzthreads_allowed() && p_mzq > 0
&& (msec < 0 || (long)dwWaitTime > p_mzq)) && (msec < 0 || (long)dwWaitTime > p_mzq))

View File

@@ -1336,9 +1336,6 @@ typedef struct {
#ifdef FEAT_GUI_GTK #ifdef FEAT_GUI_GTK
gint ch_inputHandler; /* Cookie for input */ gint ch_inputHandler; /* Cookie for input */
#endif #endif
#ifdef WIN32
int ch_inputHandler; /* ret.value of WSAAsyncSelect() */
#endif
ch_mode_T ch_mode; ch_mode_T ch_mode;
int ch_timeout; /* request timeout in msec */ int ch_timeout; /* request timeout in msec */

View File

@@ -131,10 +131,10 @@ func s:communicate(port)
call assert_false(1, 's:responseHandle was not set') call assert_false(1, 's:responseHandle was not set')
else else
call assert_equal(handle, s:responseHandle) call assert_equal(handle, s:responseHandle)
unlet s:responseHandle
endif endif
call assert_equal('got it', s:responseMsg) call assert_equal('got it', s:responseMsg)
unlet s:responseHandle
let s:responseMsg = '' let s:responseMsg = ''
call ch_sendexpr(handle, 'hello!', {'callback': function('s:RequestHandler')}) call ch_sendexpr(handle, 'hello!', {'callback': function('s:RequestHandler')})
sleep 10m sleep 10m
@@ -142,6 +142,7 @@ func s:communicate(port)
call assert_false(1, 's:responseHandle was not set') call assert_false(1, 's:responseHandle was not set')
else else
call assert_equal(handle, s:responseHandle) call assert_equal(handle, s:responseHandle)
unlet s:responseHandle
endif endif
call assert_equal('got it', s:responseMsg) call assert_equal('got it', s:responseMsg)
@@ -186,15 +187,12 @@ func s:communicate(port)
call assert_equal('ok', ch_sendexpr(handle, 'empty-request')) call assert_equal('ok', ch_sendexpr(handle, 'empty-request'))
" Reading while there is nothing available. " 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})) call assert_equal(v:none, ch_read(handle, {'timeout': 0}))
let start = reltime() let start = reltime()
call assert_equal(v:none, ch_read(handle, {'timeout': 333})) call assert_equal(v:none, ch_read(handle, {'timeout': 333}))
let elapsed = reltime(start) let elapsed = reltime(start)
call assert_true(reltimefloat(elapsed) > 0.3) call assert_true(reltimefloat(elapsed) > 0.3)
call assert_true(reltimefloat(elapsed) < 0.6) call assert_true(reltimefloat(elapsed) < 0.6)
endif
" Send without waiting for a response, then wait for a response. " Send without waiting for a response, then wait for a response.
call ch_sendexpr(handle, 'wait a bit', {'callback': 0}) call ch_sendexpr(handle, 'wait a bit', {'callback': 0})

View File

@@ -748,6 +748,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
1404,
/**/ /**/
1403, 1403,
/**/ /**/

View File

@@ -1897,10 +1897,6 @@ typedef int sock_T;
# ifdef FEAT_OLE # ifdef FEAT_OLE
# define WM_OLE (WM_APP+0) # define WM_OLE (WM_APP+0)
# endif # endif
# ifdef FEAT_CHANNEL
/* message for channel socket event */
# define WM_NETBEANS (WM_APP+1)
# endif
# endif # endif
/* Info about selected text */ /* Info about selected text */