Skip to content

Commit 9186a27

Browse files
committed
patch 7.4.1404
Problem: ch_read() doesn't time out on MS-Windows. Solution: Instead of WM_NETBEANS use select(). (Yukihiro Nakadaira)
1 parent 0106e3d commit 9186a27

7 files changed

Lines changed: 33 additions & 88 deletions

File tree

src/channel.c

Lines changed: 6 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,6 @@
5252
# define fd_close(sd) close(sd)
5353
#endif
5454

55-
#ifdef FEAT_GUI_W32
56-
extern HWND s_hwnd; /* Gvim's Window handle */
57-
#endif
58-
5955
#ifdef WIN32
6056
static int
6157
fd_read(sock_T fd, char *buf, size_t len)
@@ -295,9 +291,6 @@ add_channel(void)
295291
#endif
296292
#ifdef FEAT_GUI_GTK
297293
channel->ch_part[part].ch_inputHandler = 0;
298-
#endif
299-
#ifdef FEAT_GUI_W32
300-
channel->ch_part[part].ch_inputHandler = -1;
301294
#endif
302295
channel->ch_part[part].ch_timeout = 2000;
303296
}
@@ -421,15 +414,6 @@ channel_gui_register_one(channel_T *channel, int part)
421414
messageFromNetbeans,
422415
(gpointer)(long)channel->ch_part[part].ch_fd);
423416
# endif
424-
# else
425-
# ifdef FEAT_GUI_W32
426-
/* Tell Windows we are interested in receiving message when there
427-
* is input on the editor connection socket. */
428-
if (channel->ch_part[part].ch_inputHandler == -1)
429-
channel->ch_part[part].ch_inputHandler = WSAAsyncSelect(
430-
channel->ch_part[part].ch_fd,
431-
s_hwnd, WM_NETBEANS, FD_READ);
432-
# endif
433417
# endif
434418
# endif
435419
}
@@ -491,14 +475,6 @@ channel_gui_unregister(channel_T *channel)
491475
# endif
492476
channel->ch_part[part].ch_inputHandler = 0;
493477
}
494-
# else
495-
# ifdef FEAT_GUI_W32
496-
if (channel->ch_part[part].ch_inputHandler == 0)
497-
{
498-
WSAAsyncSelect(channel->ch_part[part].ch_fd, s_hwnd, 0, 0);
499-
channel->ch_part[part].ch_inputHandler = -1;
500-
}
501-
# endif
502478
# endif
503479
# endif
504480
}
@@ -1630,7 +1606,6 @@ channel_free_all(void)
16301606
/*
16311607
* Check for reading from "fd" with "timeout" msec.
16321608
* Return FAIL when there is nothing to read.
1633-
* Always returns OK for FEAT_GUI_W32.
16341609
*/
16351610
static int
16361611
channel_wait(channel_T *channel, sock_T fd, int timeout)
@@ -1662,12 +1637,7 @@ channel_wait(channel_T *channel, sock_T fd, int timeout)
16621637
else
16631638
#endif
16641639
{
1665-
#if defined(FEAT_GUI_W32)
1666-
/* Can't check socket for Win32 GUI, always return OK. */
1667-
ch_log(channel, "Can't check, assuming there is something to read");
1668-
return OK;
1669-
#else
1670-
# if defined(HAVE_SELECT)
1640+
#if defined(HAVE_SELECT)
16711641
struct timeval tval;
16721642
fd_set rfds;
16731643
int ret;
@@ -1679,23 +1649,22 @@ channel_wait(channel_T *channel, sock_T fd, int timeout)
16791649
for (;;)
16801650
{
16811651
ret = select((int)fd + 1, &rfds, NULL, NULL, &tval);
1682-
# ifdef EINTR
1652+
# ifdef EINTR
16831653
SOCK_ERRNO;
16841654
if (ret == -1 && errno == EINTR)
16851655
continue;
1686-
# endif
1656+
# endif
16871657
if (ret > 0)
16881658
return OK;
16891659
break;
16901660
}
1691-
# else
1661+
#else
16921662
struct pollfd fds;
16931663

16941664
fds.fd = fd;
16951665
fds.events = POLLIN;
16961666
if (poll(&fds, 1, timeout) > 0)
16971667
return OK;
1698-
# endif
16991668
#endif
17001669
}
17011670
ch_log(channel, "Nothing to read");
@@ -1764,16 +1733,6 @@ channel_read(channel_T *channel, int part, char *func)
17641733
if (len < MAXMSGSIZE)
17651734
break; /* did read everything that's available */
17661735
}
1767-
#ifdef FEAT_GUI_W32
1768-
if (use_socket && len == SOCKET_ERROR)
1769-
{
1770-
/* For Win32 GUI channel_wait() always returns OK and we handle the
1771-
* situation that there is nothing to read here.
1772-
* TODO: how about a timeout? */
1773-
if (WSAGetLastError() == WSAEWOULDBLOCK)
1774-
return;
1775-
}
1776-
#endif
17771736

17781737
/* Reading a disconnection (readlen == 0), or an error.
17791738
* TODO: call error callback. */
@@ -1970,17 +1929,12 @@ channel_handle_events(void)
19701929

19711930
for (channel = first_channel; channel != NULL; channel = channel->ch_next)
19721931
{
1973-
# ifdef FEAT_GUI_W32
1974-
/* only check the pipes */
1975-
for (part = PART_OUT; part <= PART_ERR; ++part)
1976-
# else
1977-
# ifdef CHANNEL_PIPES
1932+
# ifdef CHANNEL_PIPES
19781933
/* check the socket and pipes */
19791934
for (part = PART_SOCK; part <= PART_ERR; ++part)
1980-
# else
1935+
# else
19811936
/* only check the socket */
19821937
part = PART_SOCK;
1983-
# endif
19841938
# endif
19851939
{
19861940
fd = channel->ch_part[part].ch_fd;

src/gui_w32.c

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1927,24 +1927,6 @@ process_message(void)
19271927
}
19281928
#endif
19291929

1930-
#ifdef FEAT_CHANNEL
1931-
if (msg.message == WM_NETBEANS)
1932-
{
1933-
int part;
1934-
channel_T *channel = channel_fd2channel((sock_T)msg.wParam, &part);
1935-
1936-
if (channel != NULL)
1937-
{
1938-
/* Disable error messages, they can mess up the display and throw
1939-
* an exception. */
1940-
++emsg_off;
1941-
channel_read(channel, part, "process_message");
1942-
--emsg_off;
1943-
}
1944-
return;
1945-
}
1946-
#endif
1947-
19481930
#ifdef FEAT_SNIFF
19491931
if (sniff_request_waiting && want_sniff_request)
19501932
{
@@ -2245,7 +2227,18 @@ gui_mch_wait_for_chars(int wtime)
22452227
}
22462228

22472229
#ifdef MESSAGE_QUEUE
2248-
parse_queued_messages();
2230+
/* Check channel while waiting message. */
2231+
for (;;)
2232+
{
2233+
MSG msg;
2234+
2235+
parse_queued_messages();
2236+
2237+
if (pPeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)
2238+
|| MsgWaitForMultipleObjects(0, NULL, FALSE, 100, QS_ALLEVENTS)
2239+
!= WAIT_TIMEOUT)
2240+
break;
2241+
}
22492242
#endif
22502243

22512244
/*

src/os_win32.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1492,6 +1492,11 @@ WaitForChar(long msec)
14921492
{
14931493
DWORD dwWaitTime = dwEndTime - dwNow;
14941494

1495+
#ifdef FEAT_CHANNEL
1496+
/* Check channel while waiting input. */
1497+
if (dwWaitTime > 100)
1498+
dwWaitTime = 100;
1499+
#endif
14951500
#ifdef FEAT_MZSCHEME
14961501
if (mzthreads_allowed() && p_mzq > 0
14971502
&& (msec < 0 || (long)dwWaitTime > p_mzq))

src/structs.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1336,9 +1336,6 @@ typedef struct {
13361336
#ifdef FEAT_GUI_GTK
13371337
gint ch_inputHandler; /* Cookie for input */
13381338
#endif
1339-
#ifdef WIN32
1340-
int ch_inputHandler; /* ret.value of WSAAsyncSelect() */
1341-
#endif
13421339

13431340
ch_mode_T ch_mode;
13441341
int ch_timeout; /* request timeout in msec */

src/testdir/test_channel.vim

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -131,17 +131,18 @@ func s:communicate(port)
131131
call assert_false(1, 's:responseHandle was not set')
132132
else
133133
call assert_equal(handle, s:responseHandle)
134+
unlet s:responseHandle
134135
endif
135136
call assert_equal('got it', s:responseMsg)
136137

137-
unlet s:responseHandle
138138
let s:responseMsg = ''
139139
call ch_sendexpr(handle, 'hello!', {'callback': function('s:RequestHandler')})
140140
sleep 10m
141141
if !exists('s:responseHandle')
142142
call assert_false(1, 's:responseHandle was not set')
143143
else
144144
call assert_equal(handle, s:responseHandle)
145+
unlet s:responseHandle
145146
endif
146147
call assert_equal('got it', s:responseMsg)
147148

@@ -186,15 +187,12 @@ func s:communicate(port)
186187
call assert_equal('ok', ch_sendexpr(handle, 'empty-request'))
187188

188189
" Reading while there is nothing available.
189-
" TODO: make this work for MS-Windows
190-
if has('unix')
191-
call assert_equal(v:none, ch_read(handle, {'timeout': 0}))
192-
let start = reltime()
193-
call assert_equal(v:none, ch_read(handle, {'timeout': 333}))
194-
let elapsed = reltime(start)
195-
call assert_true(reltimefloat(elapsed) > 0.3)
196-
call assert_true(reltimefloat(elapsed) < 0.6)
197-
endif
190+
call assert_equal(v:none, ch_read(handle, {'timeout': 0}))
191+
let start = reltime()
192+
call assert_equal(v:none, ch_read(handle, {'timeout': 333}))
193+
let elapsed = reltime(start)
194+
call assert_true(reltimefloat(elapsed) > 0.3)
195+
call assert_true(reltimefloat(elapsed) < 0.6)
198196

199197
" Send without waiting for a response, then wait for a response.
200198
call ch_sendexpr(handle, 'wait a bit', {'callback': 0})

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -748,6 +748,8 @@ static char *(features[]) =
748748

749749
static int included_patches[] =
750750
{ /* Add new patch number below this line */
751+
/**/
752+
1404,
751753
/**/
752754
1403,
753755
/**/

src/vim.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1897,10 +1897,6 @@ typedef int sock_T;
18971897
# ifdef FEAT_OLE
18981898
# define WM_OLE (WM_APP+0)
18991899
# endif
1900-
# ifdef FEAT_CHANNEL
1901-
/* message for channel socket event */
1902-
# define WM_NETBEANS (WM_APP+1)
1903-
# endif
19041900
# endif
19051901

19061902
/* Info about selected text */

0 commit comments

Comments
 (0)