Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2010-08-30 14:39:43 +0400
committerCorinna Vinschen <corinna@vinschen.de>2010-08-30 14:39:43 +0400
commit92596190c4f48613d55ac7878c481d872f717d21 (patch)
tree2ae34a207f30df5c185020913a4aeea1789e99f2 /winsup/cygwin
parent98edb049e44c1630efaf8635281af211ddad3684 (diff)
* 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/ChangeLog11
-rw-r--r--winsup/cygwin/autoload.cc2
-rw-r--r--winsup/cygwin/select.cc24
-rw-r--r--winsup/cygwin/wincap.cc11
-rw-r--r--winsup/cygwin/wincap.h2
5 files changed, 46 insertions, 4 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index bcbe77b81..fba8035f7 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 30bbec702..07272af53 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 41636d179..611367b31 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 889998c79..39b1c7548 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 6a698d2f0..8f027d089 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
};