JdBP>> "Presentation Manager is multithreaded, always has
JdBP>> been, and has always had multiple input queues,
JdBP>> one per application thread."
HR> Yeah! But it has a *single* System Message Queue. This one is that
HR> accepts events from keyboard and mouse. The multiple application
HR> message queues are the other side.
And as Mike Ruskai pointed out, that queue is *not* locked and *not* the cause
of the problem. It doesn't have to be locked. When a thread that is
executing WinGetMsg() takes a message from the raw input queue, it only needs
to lock the queue whilst it is extracting the message. It doesn't need to
hold the queue locked once it has the message, which means that it isn't
preventing other threads from accessing the raw input queue immediately
afterwards whilst it goes away and calls WinDispatchMsg().
In any case, if this *were* a problem with the raw input queue, it would be a
problem on Windows NT as well, because Windows NT *also* has a single raw
input queue. But Windows NT is famous for *not* having a "SIQ problem",
therefore the problem is not caused by there being a single raw input queue.
As I said, the letter 'S' in "SIQ" *does* *not* *stand* *for* *"single"*.
Your explanation of how the raw input queue is blocked
HR> If you PM application is in thread 1 working on a message
HR> received from PM no other system message can and will be
HR> processed until this application thread returns to PM. Therfore
HR> the single system message queue is blocked. No event can go to
HR> any other application or thread from there.
is simply wrong. As, too, is your understanding of how PM applications work:
HR> If the PM receives an event foran PM application it will search
HR> in its list to find which application ownes the focus. Then
HR> this event is put (from system message queue) into the
HR> applications message queue. After that the PM calls itself
HR> the application to handle that message. Now the application
HR> controls the PM until it returns. After return the PM showns
HR> into the system message queue for the next message it received
HR> from keyboard/mouse to call the same or another application
HR> with that message.
In almost every respect your explanation is entirely backwards. Presentation
Manager (and indeed Windows and the Macintosh) are "pull event" systems not
"push event" systems. You seem to think that PMSHELL.EXE *is* Presentation
Manager, and that it pushes events to other applications. This is rubbish.
PMSHELL.EXE is simply the first application that uses the Presentation Manager
library that happens to run. PMSHELL.EXE *is not* Presentation Manager.
PMSHELL.EXE is the Workplace Shell *application*, that just happens to *use*
Presentation Manager.
There is no single process that contains Presentation Manager. You cannot
point to an executable and say "that is the PM server process". PM is not X.
It doesn't *have* a single server process that pushes events out to all other
processes. Presentation Manager is a co”perative effort of all of the
applications that use the PM library to present a graphical user interface.
And it uses a "pull event" paradigm.
Threads call WinGetMsg(), and pull any events that they are interested in from
various places. (WM_PAINT events, for example, are in fact generated on the
fly internally within WinGetMsg(). They don't sit in the thread's message
queue at all. This is why multiple WinInvalidateRect() calls might only
result in a single WM_PAINT message.) WinGetMsg() pulls messages from the raw
keyboard input queue if it notices that it is the thread that owns the window
with the input focus for the current desktop. It pulls messages out of the
thread's message queue that have been posted to it with WinPostMsg(). It
pulls any messages that have been sent to it by other threads with
WinSendMsg(). Presentation Manager doesn't "call the application" and push
events onto it. The application's threads call the Presentation Manager
library's WinGetMsg() function and *pull* events from various places, which
they then distribute to their individual window functions by then calling
WinDispatchMsg().
Moreover, your idea that the application "returns back to PM" whereupon PM
unlocks the raw input queue and goes on to process the next message is also
completely backwards. The synchronous nature of the "Synchronous Input Queue"
problem is not that the raw input queue is locked. It *isn't* locked once
WinGetMsg() has returned (PM returns to the application, not the other way
around, by the way.) and the application is deciding what to do with the
message that it has obtained.
The synchronous nature of the SIQ problem is that focus change processing is
synchronous. (I admit that I wasn't too clear about this in my previous
message. But this isn't the OS2PROG echo where one normally goes into this
sort of detail.) All of the WM_ACTIVATE, WM_FOCUS, and WM_SETSELECTION
messages that result from WinFocusChange() are sent synchronously, as if by
WinSendMsg(). This means that the focus change will block partway through
changing the focus if one of the currently active windows isn't calling
WinGetMsg() frequently, or at all. (You'll notice that you'll never see a
known "bad" application lock Presentation Manager if you never give it the
input focus or make any of its windows active.)
The "desynchronisation" fix in OS/2 Warp is to modify WinFocusChange() so that
the message sending will time out after a fixed period. (There's no timeout
parameter to WinSendMsg() so it must be using an internal, not publically
accessible, function to do this.) If a thread refuses to process and
acknowledge a WM_ACTIVATE, WM_SETSELECTION, or WM_SETFOCUS message within that
time, WinFocusChange() simply acts as if the message *had* been acknowledged,
and also marks the offending (WC_FRAME) window as "unresponsive" (and paints a
border around it) in case the same thing were to happen in the future.
¯ JdeBP ®
--- FleetStreet 1.22 NR
143/1
* Origin: JdeBP's point, using Squish (2:257/609.3)
|