]> asedeno.scripts.mit.edu Git - PuTTY_svn.git/commitdiff
Avoid leaving unread Windows messages in the queue.
authorSimon Tatham <anakin@pobox.com>
Fri, 25 Oct 2013 17:44:02 +0000 (17:44 +0000)
committerSimon Tatham <anakin@pobox.com>
Fri, 25 Oct 2013 17:44:02 +0000 (17:44 +0000)
Jochen Erwied points out that once you've used PeekMessage to remove
_one_ message from the message queue, MsgWaitForMultipleObjects will
consider the whole queue to have been 'read', or at least looked at
and deemed uninteresting, and so it will block until a further message
comes in. Hence, my change in r10040 which stops us from looping on
PeekMessage until the queue is empty has the effect of causing the
rest of the message queue not to be acted on until a new message comes
in to unblock it. Fix by checking if the queue is nonempty in advance
of calling MsgWaitForMultipleObjects, and if so, giving it a zero
timeout just as we do if there's a pending toplevel callback.

git-svn-id: http://svn.tartarus.org/sgt/putty@10052 cda61777-01e9-0310-a592-d414129be87e

windows/window.c

index ec6ec3e87ffbb9f55155f52b7452f0b4e789a3a9..6baa45a79e95658bd0c3a2081858b45557c77a41 100644 (file)
@@ -849,7 +849,24 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
        int nhandles, n;
         DWORD timeout;
 
-        if (toplevel_callback_pending()) {
+        if (toplevel_callback_pending() || GetQueueStatus(QS_ALLINPUT)) {
+            /*
+             * If we have anything we'd like to do immediately, set
+             * the timeout for MsgWaitForMultipleObjects to zero so
+             * that we'll only do a quick check of our handles and
+             * then get on with whatever that was.
+             *
+             * One such option is a pending toplevel callback. The
+             * other is a non-empty Windows message queue, which you'd
+             * think we could leave to MsgWaitForMultipleObjects to
+             * check for us along with all the handles, but in fact we
+             * can't because once PeekMessage in one iteration of this
+             * loop has removed a message from the queue, the whole
+             * queue is considered uninteresting by the next
+             * invocation of MWFMO. So we check ourselves whether the
+             * message queue is non-empty, and if so, set this timeout
+             * to zero to ensure MWFMO doesn't block.
+             */
             timeout = 0;
         } else {
             timeout = INFINITE;