mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-10 09:58:01 +00:00
Stop Windows PuTTY becoming unresponsive if server floods us.
This was an old bug, fixed around 0.59, which apparently regressed
when I rewrote the main event loop using the toplevel_callback
mechanism.
Investigation just now suggests that it has to do with my faulty
assumption that Windows PeekMessage would deliver messages in its
message queue in FIFO order (i.e. that the thing calling itself a
message queue is actually a _queue_). In fact my WM_NETEVENT seems to
like to jump the queue, so that once a steady stream of them starts
arriving, we never do anything else in the main event loop (except
deal with handles).
Worked around in a simple and slightly bodgy way, namely, we don't
stop looping on PeekMessage and run our toplevel callbacks until we've
either run out of messages completely or else seen at least one that
_isn't_ a WM_NETEVENT. That way we should reliably interleave NETEVENT
processing with processing of other stuff.
(cherry picked from commit 7d97c2a8fd
)
This commit is contained in:
parent
74f50c9f21
commit
0db409bc07
@ -888,12 +888,34 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
|
||||
} else
|
||||
sfree(handles);
|
||||
|
||||
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
|
||||
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
|
||||
if (msg.message == WM_QUIT)
|
||||
goto finished; /* two-level break */
|
||||
|
||||
if (!(IsWindow(logbox) && IsDialogMessage(logbox, &msg)))
|
||||
DispatchMessage(&msg);
|
||||
|
||||
/*
|
||||
* WM_NETEVENT messages seem to jump ahead of others in
|
||||
* the message queue. I'm not sure why; the docs for
|
||||
* PeekMessage mention that messages are prioritised in
|
||||
* some way, but I'm unclear on which priorities go where.
|
||||
*
|
||||
* Anyway, in practice I observe that WM_NETEVENT seems to
|
||||
* jump to the head of the queue, which means that if we
|
||||
* were to only process one message every time round this
|
||||
* loop, we'd get nothing but NETEVENTs if the server
|
||||
* flooded us with data, and stop responding to any other
|
||||
* kind of window message. So instead, we keep on round
|
||||
* this loop until we've consumed at least one message
|
||||
* that _isn't_ a NETEVENT, or run out of messages
|
||||
* completely (whichever comes first). And we don't go to
|
||||
* run_toplevel_callbacks (which is where the netevents
|
||||
* are actually processed, causing fresh NETEVENT messages
|
||||
* to appear) until we've done this.
|
||||
*/
|
||||
if (msg.message != WM_NETEVENT)
|
||||
break;
|
||||
}
|
||||
|
||||
run_toplevel_callbacks();
|
||||
|
Loading…
Reference in New Issue
Block a user