diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2010-08-30 10:39:43 +0000 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2010-08-30 10:39:43 +0000 |
commit | 92596190c4f48613d55ac7878c481d872f717d21 (patch) | |
tree | 2ae34a207f30df5c185020913a4aeea1789e99f2 /winsup/cygwin | |
parent | 98edb049e44c1630efaf8635281af211ddad3684 (diff) | |
download | newlib-92596190c4f48613d55ac7878c481d872f717d21.zip newlib-92596190c4f48613d55ac7878c481d872f717d21.tar.gz newlib-92596190c4f48613d55ac7878c481d872f717d21.tar.bz2 |
* 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.
Diffstat (limited to 'winsup/cygwin')
-rw-r--r-- | winsup/cygwin/ChangeLog | 11 | ||||
-rw-r--r-- | winsup/cygwin/autoload.cc | 2 | ||||
-rw-r--r-- | winsup/cygwin/select.cc | 24 | ||||
-rw-r--r-- | winsup/cygwin/wincap.cc | 11 | ||||
-rw-r--r-- | winsup/cygwin/wincap.h | 2 |
5 files changed, 46 insertions, 4 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index bcbe77b..fba8035 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -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. diff --git a/winsup/cygwin/autoload.cc b/winsup/cygwin/autoload.cc index 30bbec7..07272af 100644 --- a/winsup/cygwin/autoload.cc +++ b/winsup/cygwin/autoload.cc @@ -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) diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc index 41636d1..611367b 100644 --- a/winsup/cygwin/select.cc +++ b/winsup/cygwin/select.cc @@ -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 ()); diff --git a/winsup/cygwin/wincap.cc b/winsup/cygwin/wincap.cc index 889998c..39b1c75 100644 --- a/winsup/cygwin/wincap.cc +++ b/winsup/cygwin/wincap.cc @@ -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)); diff --git a/winsup/cygwin/wincap.h b/winsup/cygwin/wincap.h index 6a698d2..8f027d0 100644 --- a/winsup/cygwin/wincap.h +++ b/winsup/cygwin/wincap.h @@ -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 }; |