[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH v2] implement full-blown select(2) for winsock
From: |
Bruno Haible |
Subject: |
Re: [PATCH v2] implement full-blown select(2) for winsock |
Date: |
Sat, 4 Oct 2008 19:05:00 +0200 |
User-agent: |
KMail/1.5.4 |
Hi Paolo,
> > For reference, here is the code that is in use in clisp to detect whether
> > reading from a handle would hang or return immediately. The deal with
> > ENABLE_LINE_INPUT is that PeekConsoleInput will say "yes there is something
> > is available" as soon as the user has started typing a line, but ReadFile
> > will hang until the user presses Return.
>
> Yes, it makes sense to add it to the select/poll emulations. I didn't
> know about ENABLE_LINE_INPUT.
Well, this ENABLE_LINE_INPUT mode is the first obstacle when you try to
implement the Lisp function READ-CHAR-NO-HANG from a console window, and
it hangs between the moment you type the first character of the line and
the final Return...
I propose this code, based on the one from clisp (which I wrote and extensively
tested years ago). Like you, I cannot test it for the moment. But anyway.
Also, when GetNumberOfConsoleInputEvents fails, indicating that the handle
refers to a character device other than a console (such as "NUL"), it's
better to say that there is something to be read, so I changed
except = TRUE;
in this case to
read = TRUE;
2008-10-04 Bruno Haible <address@hidden>
* lib/winsock-select.c (win32_poll_handle): Improve code for character
devices (both consoles and others).
*** lib/winsock-select.c.orig 2008-10-04 18:57:04.000000000 +0200
--- lib/winsock-select.c 2008-10-04 18:55:30.000000000 +0200
***************
*** 82,88 ****
{
BOOL read, write, except;
int i, ret;
- INPUT_RECORD *irbuffer;
DWORD avail, nbuffer;
BOOL bRet;
IO_STATUS_BLOCK iosb;
--- 82,87 ----
***************
*** 142,158 ****
{
nbuffer = avail = 0;
bRet = GetNumberOfConsoleInputEvents (h, &nbuffer);
! if (!bRet || nbuffer == 0)
! except = TRUE;
!
! irbuffer = (INPUT_RECORD *) alloca (nbuffer * sizeof (INPUT_RECORD));
! bRet = PeekConsoleInput (h, irbuffer, nbuffer, &avail);
! if (!bRet || avail == 0)
! except = TRUE;
!
! for (i = 0; i < avail; i++)
! if (irbuffer[i].EventType == KEY_EVENT)
read = TRUE;
}
break;
--- 141,197 ----
{
nbuffer = avail = 0;
bRet = GetNumberOfConsoleInputEvents (h, &nbuffer);
! if (bRet)
! {
! /* It's a console. */
! if (nbuffer == 0)
! except = TRUE;
! else
! {
! INPUT_RECORD *irbuffer =
! (INPUT_RECORD *) alloca (nbuffer * sizeof (INPUT_RECORD));
! bRet = PeekConsoleInput (h, irbuffer, nbuffer, &avail);
! if (!bRet || avail == 0)
! except = TRUE;
! else
! {
! DWORD mode;
! bRet = GetConsoleMode (h, &mode);
! if (!bRet)
! except = TRUE;
! else if (mode & ENABLE_LINE_INPUT)
! {
! /* Look out for a Key-Down event corresponding to
! CR/LF. */
! for (i = 0; i < avail; i++)
! if (irbuffer[i].EventType == KEY_EVENT
! && irbuffer[i].Event.KeyEvent.bKeyDown
! && irbuffer[i].Event.KeyEvent.uAsciiChar == CR)
! {
! read = TRUE;
! break;
! }
! }
! else
! {
! /* Look out for any Key-Down event. */
! for (i = 0; i < avail; i++)
! if (irbuffer[i].EventType == KEY_EVENT
! && irbuffer[i].Event.KeyEvent.bKeyDown
! && irbuffer[i].Event.KeyEvent.uAsciiChar != 0)
! {
! read = TRUE;
! break;
! }
! }
! }
! }
! }
! else
! {
! /* Not a console. Possibly a device such as "NUL". */
read = TRUE;
+ }
}
break;