* autoload.cc (MsgWaitForMultipleObjectsEx): Define.

(MsgWaitForMultipleObjects): Remove.
	* select.cc (select_stuff::wait): Use MsgWaitForMultipleObjectsEx with
	QS_ALLPOSTMESSAGE and, if possible, MWMO_INPUTAVAILABLE flags.  Explain
	why.  Fix a potential crash due to a NULL pointer in WAIT_FAILED case.
	(peek_windows): Use filter pattern on NT4.  Explain why.
	* wincap.h (wincaps::has_mwmo_inputavailable): New element.
	* wincap.cc: Implement above element throughout.
This commit is contained in:
Corinna Vinschen 2010-08-30 10:39:43 +00:00
parent 98edb049e4
commit 92596190c4
5 changed files with 46 additions and 4 deletions

View File

@ -1,3 +1,14 @@
2010-08-30 Corinna Vinschen <corinna@vinschen.de>
* autoload.cc (MsgWaitForMultipleObjectsEx): Define.
(MsgWaitForMultipleObjects): Remove.
* select.cc (select_stuff::wait): Use MsgWaitForMultipleObjectsEx with
QS_ALLPOSTMESSAGE and, if possible, MWMO_INPUTAVAILABLE flags. Explain
why. Fix a potential crash due to a NULL pointer in WAIT_FAILED case.
(peek_windows): Use filter pattern on NT4. Explain why.
* wincap.h (wincaps::has_mwmo_inputavailable): New element.
* wincap.cc: Implement above element throughout.
2010-08-29 Christopher Faylor <me+cygwin@cgf.cx>
* winlean.h: New file.

View File

@ -357,7 +357,7 @@ LoadDLLfunc (GetWindowThreadProcessId, 8, user32)
LoadDLLfunc (GetUserObjectInformationW, 20, user32)
LoadDLLfunc (MessageBeep, 4, user32)
LoadDLLfunc (MessageBoxA, 16, user32)
LoadDLLfunc (MsgWaitForMultipleObjects, 20, user32)
LoadDLLfunc (MsgWaitForMultipleObjectsEx, 20, user32)
LoadDLLfunc (OpenClipboard, 4, user32)
LoadDLLfunc (PeekMessageA, 20, user32)
LoadDLLfunc (PostMessageA, 16, user32)

View File

@ -287,7 +287,17 @@ select_stuff::wait (fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
if (!windows_used)
wait_ret = WaitForMultipleObjects (m, w4, FALSE, ms);
else
wait_ret = MsgWaitForMultipleObjects (m, w4, FALSE, ms, QS_ALLINPUT);
/* Using MWMO_INPUTAVAILABLE is the officially supported solution for
the problem that the call to PeekMessage disarms the queue state
so that a subsequent MWFMO hangs, even if there are still messages
in the queue. Unfortunately this flag didn't exist prior to Win2K,
so for NT4 we fall back to a different usage of PeekMessage in
peek_windows. See there for more details. */
wait_ret =
MsgWaitForMultipleObjectsEx (m, w4, ms,
QS_ALLINPUT | QS_ALLPOSTMESSAGE,
wincap.has_mwmo_inputavailable ()
? MWMO_INPUTAVAILABLE : 0);
switch (wait_ret)
{
@ -296,7 +306,8 @@ select_stuff::wait (fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
set_sig_errno (EINTR);
return -1;
case WAIT_FAILED:
select_printf ("WaitForMultipleObjects failed");
system_printf ("WaitForMultipleObjects failed");
s = &start;
s->set_select_errno ();
return -1;
case WAIT_TIMEOUT:
@ -1531,7 +1542,14 @@ peek_windows (select_record *me, bool)
if (me->read_selected && me->read_ready)
return 1;
if (PeekMessage (&m, (HWND) h, 0, 0, PM_NOREMOVE))
/* On NT4 we use a filter pattern which allows to use QS_ALLPOSTMESSAGE
to keep the queue state as unread. Note that this only works if the
application itself does not call PeekMessage or GetQueueState the wrong
way. But there's no way around it. On Win2K and later we rather use
MsgWaitForMultipleObjectsEx(MWMO_INPUTAVAILABLE). */
if (PeekMessage (&m, (HWND) h, 0,
wincap.has_mwmo_inputavailable () ? 0 : UINT_MAX - 1,
PM_NOREMOVE))
{
me->read_ready = true;
select_printf ("window %d(%p) ready", me->fd, me->fh->get_handle ());

View File

@ -59,6 +59,7 @@ wincaps wincap_unknown __attribute__((section (".cygwin_dll_common"), shared)) =
has_broken_alloc_console:false,
has_always_all_codepages:false,
has_localenames:false,
has_mwmo_inputavailable:false,
};
wincaps wincap_nt4 __attribute__((section (".cygwin_dll_common"), shared)) = {
@ -99,6 +100,7 @@ wincaps wincap_nt4 __attribute__((section (".cygwin_dll_common"), shared)) = {
has_broken_alloc_console:false,
has_always_all_codepages:false,
has_localenames:false,
has_mwmo_inputavailable:false,
};
wincaps wincap_nt4sp4 __attribute__((section (".cygwin_dll_common"), shared)) = {
@ -139,6 +141,7 @@ wincaps wincap_nt4sp4 __attribute__((section (".cygwin_dll_common"), shared)) =
has_broken_alloc_console:false,
has_always_all_codepages:false,
has_localenames:false,
has_mwmo_inputavailable:false,
};
wincaps wincap_2000 __attribute__((section (".cygwin_dll_common"), shared)) = {
@ -179,6 +182,7 @@ wincaps wincap_2000 __attribute__((section (".cygwin_dll_common"), shared)) = {
has_broken_alloc_console:false,
has_always_all_codepages:false,
has_localenames:false,
has_mwmo_inputavailable:true,
};
wincaps wincap_2000sp4 __attribute__((section (".cygwin_dll_common"), shared)) = {
@ -219,6 +223,7 @@ wincaps wincap_2000sp4 __attribute__((section (".cygwin_dll_common"), shared)) =
has_broken_alloc_console:false,
has_always_all_codepages:false,
has_localenames:false,
has_mwmo_inputavailable:true,
};
wincaps wincap_xp __attribute__((section (".cygwin_dll_common"), shared)) = {
@ -259,6 +264,7 @@ wincaps wincap_xp __attribute__((section (".cygwin_dll_common"), shared)) = {
has_broken_alloc_console:false,
has_always_all_codepages:false,
has_localenames:false,
has_mwmo_inputavailable:true,
};
wincaps wincap_xpsp1 __attribute__((section (".cygwin_dll_common"), shared)) = {
@ -299,6 +305,7 @@ wincaps wincap_xpsp1 __attribute__((section (".cygwin_dll_common"), shared)) = {
has_broken_alloc_console:false,
has_always_all_codepages:false,
has_localenames:false,
has_mwmo_inputavailable:true,
};
wincaps wincap_xpsp2 __attribute__((section (".cygwin_dll_common"), shared)) = {
@ -339,6 +346,7 @@ wincaps wincap_xpsp2 __attribute__((section (".cygwin_dll_common"), shared)) = {
has_broken_alloc_console:false,
has_always_all_codepages:false,
has_localenames:false,
has_mwmo_inputavailable:true,
};
wincaps wincap_2003 __attribute__((section (".cygwin_dll_common"), shared)) = {
@ -379,6 +387,7 @@ wincaps wincap_2003 __attribute__((section (".cygwin_dll_common"), shared)) = {
has_broken_alloc_console:false,
has_always_all_codepages:false,
has_localenames:false,
has_mwmo_inputavailable:true,
};
wincaps wincap_vista __attribute__((section (".cygwin_dll_common"), shared)) = {
@ -419,6 +428,7 @@ wincaps wincap_vista __attribute__((section (".cygwin_dll_common"), shared)) = {
has_broken_alloc_console:false,
has_always_all_codepages:true,
has_localenames:true,
has_mwmo_inputavailable:true,
};
wincaps wincap_7 __attribute__((section (".cygwin_dll_common"), shared)) = {
@ -459,6 +469,7 @@ wincaps wincap_7 __attribute__((section (".cygwin_dll_common"), shared)) = {
has_broken_alloc_console:true,
has_always_all_codepages:true,
has_localenames:true,
has_mwmo_inputavailable:true,
};
wincapc wincap __attribute__((section (".cygwin_dll_common"), shared));

View File

@ -51,6 +51,7 @@ struct wincaps
unsigned has_broken_alloc_console : 1;
unsigned has_always_all_codepages : 1;
unsigned has_localenames : 1;
unsigned has_mwmo_inputavailable : 1;
};
class wincapc
@ -107,6 +108,7 @@ public:
bool IMPLEMENT (has_broken_alloc_console)
bool IMPLEMENT (has_always_all_codepages)
bool IMPLEMENT (has_localenames)
bool IMPLEMENT (has_mwmo_inputavailable)
#undef IMPLEMENT
};