* 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:
@ -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>
|
2010-08-29 Christopher Faylor <me+cygwin@cgf.cx>
|
||||||
|
|
||||||
* winlean.h: New file.
|
* winlean.h: New file.
|
||||||
|
@ -357,7 +357,7 @@ LoadDLLfunc (GetWindowThreadProcessId, 8, user32)
|
|||||||
LoadDLLfunc (GetUserObjectInformationW, 20, user32)
|
LoadDLLfunc (GetUserObjectInformationW, 20, user32)
|
||||||
LoadDLLfunc (MessageBeep, 4, user32)
|
LoadDLLfunc (MessageBeep, 4, user32)
|
||||||
LoadDLLfunc (MessageBoxA, 16, user32)
|
LoadDLLfunc (MessageBoxA, 16, user32)
|
||||||
LoadDLLfunc (MsgWaitForMultipleObjects, 20, user32)
|
LoadDLLfunc (MsgWaitForMultipleObjectsEx, 20, user32)
|
||||||
LoadDLLfunc (OpenClipboard, 4, user32)
|
LoadDLLfunc (OpenClipboard, 4, user32)
|
||||||
LoadDLLfunc (PeekMessageA, 20, user32)
|
LoadDLLfunc (PeekMessageA, 20, user32)
|
||||||
LoadDLLfunc (PostMessageA, 16, user32)
|
LoadDLLfunc (PostMessageA, 16, user32)
|
||||||
|
@ -287,7 +287,17 @@ select_stuff::wait (fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
|
|||||||
if (!windows_used)
|
if (!windows_used)
|
||||||
wait_ret = WaitForMultipleObjects (m, w4, FALSE, ms);
|
wait_ret = WaitForMultipleObjects (m, w4, FALSE, ms);
|
||||||
else
|
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)
|
switch (wait_ret)
|
||||||
{
|
{
|
||||||
@ -296,7 +306,8 @@ select_stuff::wait (fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
|
|||||||
set_sig_errno (EINTR);
|
set_sig_errno (EINTR);
|
||||||
return -1;
|
return -1;
|
||||||
case WAIT_FAILED:
|
case WAIT_FAILED:
|
||||||
select_printf ("WaitForMultipleObjects failed");
|
system_printf ("WaitForMultipleObjects failed");
|
||||||
|
s = &start;
|
||||||
s->set_select_errno ();
|
s->set_select_errno ();
|
||||||
return -1;
|
return -1;
|
||||||
case WAIT_TIMEOUT:
|
case WAIT_TIMEOUT:
|
||||||
@ -1531,7 +1542,14 @@ peek_windows (select_record *me, bool)
|
|||||||
if (me->read_selected && me->read_ready)
|
if (me->read_selected && me->read_ready)
|
||||||
return 1;
|
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;
|
me->read_ready = true;
|
||||||
select_printf ("window %d(%p) ready", me->fd, me->fh->get_handle ());
|
select_printf ("window %d(%p) ready", me->fd, me->fh->get_handle ());
|
||||||
|
@ -59,6 +59,7 @@ wincaps wincap_unknown __attribute__((section (".cygwin_dll_common"), shared)) =
|
|||||||
has_broken_alloc_console:false,
|
has_broken_alloc_console:false,
|
||||||
has_always_all_codepages:false,
|
has_always_all_codepages:false,
|
||||||
has_localenames:false,
|
has_localenames:false,
|
||||||
|
has_mwmo_inputavailable:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincaps wincap_nt4 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
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_broken_alloc_console:false,
|
||||||
has_always_all_codepages:false,
|
has_always_all_codepages:false,
|
||||||
has_localenames:false,
|
has_localenames:false,
|
||||||
|
has_mwmo_inputavailable:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincaps wincap_nt4sp4 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
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_broken_alloc_console:false,
|
||||||
has_always_all_codepages:false,
|
has_always_all_codepages:false,
|
||||||
has_localenames:false,
|
has_localenames:false,
|
||||||
|
has_mwmo_inputavailable:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincaps wincap_2000 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
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_broken_alloc_console:false,
|
||||||
has_always_all_codepages:false,
|
has_always_all_codepages:false,
|
||||||
has_localenames:false,
|
has_localenames:false,
|
||||||
|
has_mwmo_inputavailable:true,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincaps wincap_2000sp4 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
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_broken_alloc_console:false,
|
||||||
has_always_all_codepages:false,
|
has_always_all_codepages:false,
|
||||||
has_localenames:false,
|
has_localenames:false,
|
||||||
|
has_mwmo_inputavailable:true,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincaps wincap_xp __attribute__((section (".cygwin_dll_common"), shared)) = {
|
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_broken_alloc_console:false,
|
||||||
has_always_all_codepages:false,
|
has_always_all_codepages:false,
|
||||||
has_localenames:false,
|
has_localenames:false,
|
||||||
|
has_mwmo_inputavailable:true,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincaps wincap_xpsp1 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
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_broken_alloc_console:false,
|
||||||
has_always_all_codepages:false,
|
has_always_all_codepages:false,
|
||||||
has_localenames:false,
|
has_localenames:false,
|
||||||
|
has_mwmo_inputavailable:true,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincaps wincap_xpsp2 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
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_broken_alloc_console:false,
|
||||||
has_always_all_codepages:false,
|
has_always_all_codepages:false,
|
||||||
has_localenames:false,
|
has_localenames:false,
|
||||||
|
has_mwmo_inputavailable:true,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincaps wincap_2003 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
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_broken_alloc_console:false,
|
||||||
has_always_all_codepages:false,
|
has_always_all_codepages:false,
|
||||||
has_localenames:false,
|
has_localenames:false,
|
||||||
|
has_mwmo_inputavailable:true,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincaps wincap_vista __attribute__((section (".cygwin_dll_common"), shared)) = {
|
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_broken_alloc_console:false,
|
||||||
has_always_all_codepages:true,
|
has_always_all_codepages:true,
|
||||||
has_localenames:true,
|
has_localenames:true,
|
||||||
|
has_mwmo_inputavailable:true,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincaps wincap_7 __attribute__((section (".cygwin_dll_common"), shared)) = {
|
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_broken_alloc_console:true,
|
||||||
has_always_all_codepages:true,
|
has_always_all_codepages:true,
|
||||||
has_localenames:true,
|
has_localenames:true,
|
||||||
|
has_mwmo_inputavailable:true,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincapc wincap __attribute__((section (".cygwin_dll_common"), shared));
|
wincapc wincap __attribute__((section (".cygwin_dll_common"), shared));
|
||||||
|
@ -51,6 +51,7 @@ struct wincaps
|
|||||||
unsigned has_broken_alloc_console : 1;
|
unsigned has_broken_alloc_console : 1;
|
||||||
unsigned has_always_all_codepages : 1;
|
unsigned has_always_all_codepages : 1;
|
||||||
unsigned has_localenames : 1;
|
unsigned has_localenames : 1;
|
||||||
|
unsigned has_mwmo_inputavailable : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
class wincapc
|
class wincapc
|
||||||
@ -107,6 +108,7 @@ public:
|
|||||||
bool IMPLEMENT (has_broken_alloc_console)
|
bool IMPLEMENT (has_broken_alloc_console)
|
||||||
bool IMPLEMENT (has_always_all_codepages)
|
bool IMPLEMENT (has_always_all_codepages)
|
||||||
bool IMPLEMENT (has_localenames)
|
bool IMPLEMENT (has_localenames)
|
||||||
|
bool IMPLEMENT (has_mwmo_inputavailable)
|
||||||
|
|
||||||
#undef IMPLEMENT
|
#undef IMPLEMENT
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user