TIP: Click on subject to list as thread! ANSI
echo: os2
to: Jonathan de Boyne Pollard
from: Herbert Rosenau
date: 1999-12-05 00:44:10
subject: Clunker update

 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
 HR>> that accepts events from keyboard and mouse. The multiple
 HR>> application message queues are the other side.

 JdBP> And as Mike Ruskai pointed out, that queue is *not* locked and
 JdBP> *not* the cause of the problem.  It doesn't have to be locked. 

It doesn't! It is the PM (pmshell.exe) that is locked while it is calling the
application. Her ist not the application callin PM - PM is calling the
application! 

In WinInitialise() the application takes its flow control to PM and PM calls
it back.

It looks like

app -> calls PM -> return -> app


Real it is a reverse stack:

app -> WinInitialise() --- until WinTerminate() PM controls the flow of it

Here it makes the reverse stack ready. The first time an application calls
WinGetMsg() it losts (for that thread) the flow control to PM.

PM calls the application each time it is ready to send an system message to
it. Then its waits for return of that message to send the next one. 

Inside PM:

	app -> calls WinGetMsg() -> hold app until message from system message
				queue received.
		Then CALL the application. Here is NO return from WingetMsg()

 JdBP> When a thread that is executing WinGetMsg() takes a message
 JdBP> from the raw input queue, it only needs to lock the queue
 JdBP> whilst it is extracting the message.  

No. No application (except PM itself) is able to receive a message from system 
message queue. The only receiver is PM itself. PM puts the message (like any
other sended message from any source into the message queue of the receiving
application. Then it calls the application to work on it.

 JdBP> It doesn't need to hold the queue locked once it has the
 JdBP> message, which means that it isn't preventing other threads
 JdBP> from accessing the raw input queue immediately afterwards
 JdBP> whilst it goes away and calls WinDispatchMsg().

WinDispatchMessage() does nothing than finding the right message procedure and 
calls it. This point acts like a simple subroutine. Only the return from an
message gets control back to PM if PM is the sender. Then PM can read the next 
message from system message queue.

If you write a multi threaded PM application you'll see that PM is allocation
the contol of thread 1 (or the thread that is calling WinInitialise() the
first time inside app. Other threads are inependant from system message queue. 
They would never receive a mesage from it - other than over thread 1 and
WinDispatchMessage(). Any other thread in any application can proceed with any 
message handling. It my sen/post messages to any receiver it has to do -
without blocking the system message queue. 

To do that the right way PM manipulates the stackpointer of each thread it
controls!

 JdBP> In any case, if this *were* a problem with the raw input queue,
 JdBP> it would be a problem on Windows NT as well, because Windows NT
 JdBP> *also* has a single raw input queue.  But Windows NT is famous
 JdBP> for *not* having a "SIQ problem", therefore the problem is not
 JdBP> caused by there being a single raw input queue. As I said, the
 JdBP> letter 'S' in "SIQ" *does* *not* *stand* *for* *"single"*.

It stands for 'SYSTEM' not for single. The system message queue is the single
queue between the input devices (keyboard, mouse, touch screen...) and the
applications message queue. This queue serialises the events from input
devices so that each event can find its ordinate window. 

 JdBP> Your explanation of how the raw input queue is blocked 
 JdBP> is simply wrong.  As, too, is your understanding of how PM
 JdBP> applications work:

No. You should read the readbooks.

 JdBP> In almost every respect your explanation is entirely backwards.
 JdBP>  Presentation Manager (and indeed Windows and the Macintosh)
 JdBP> are "pull event" systems not "push event" systems.  You seem to
 JdBP> think that PMSHELL.EXE *is* Presentation Manager, and that it
 JdBP> pushes events to other applications.  This is rubbish.
 JdBP> PMSHELL.EXE is simply the first application that uses the
 JdBP> Presentation Manager library that happens to run.  PMSHELL.EXE
 JdBP> *is not* Presentation Manager. PMSHELL.EXE is the Workplace
 JdBP> Shell *application*, that just happens to *use* Presentation
 JdBP> Manager.

No. PMSHELL.EXE is a dual application. It runs twice.

The first instance (the lower PID) is the PM control - and the second (the
higher PID) is the WPS - a 'simple' user application.

 JdBP> There is no single process that contains Presentation Manager. 

There IS. It is called pmshell.exe - first instance.

 JdBP> You cannot point to an executable and say "that is the PM
 JdBP> server process".  PM is not X.  

Right. But the server process already exists. It has only one real (not
multiple virtual consoles).

 JdBP> It doesn't *have* a single server process that pushes events
 JdBP> out to all other processes. Presentation Manager is a
 JdBP> co”perative effort of all of the applications that use the PM
 JdBP> library to present a graphical user interface.  And it uses a
 JdBP> "pull event" paradigm.  

You're wrong. 

 JdBP> It pulls messages out of the thread's message queue that have
 JdBP> been posted to it with WinPostMsg(). It pulls any messages that
 JdBP> have been sent to it by other threads with WinSendMsg(). 
 JdBP> Presentation Manager doesn't "call the application" and push
 JdBP> events onto it.  The application's threads call the
 JdBP> Presentation Manager library's WinGetMsg() function and *pull*
 JdBP> events from various places, which they then distribute to their
 JdBP> individual window functions by then calling WinDispatchMsg().

You should read the PM redbooks. There are some interesting details how are
the PM and PM apps are structured.

 JdBP> Moreover, your idea that the application "returns back to PM"
 JdBP> whereupon PM unlocks the raw input queue and goes on to process
 JdBP> the next message is also completely backwards.

You goes a wrong way. Not the application goes back. The PM receives the
result of the system message it receives an then in sends the next one - if it 
exists. The PM hooks on an timer to fit out that a message my never return -
not an users application. This (never returned) app will be sorted out from
receiving any future system message (until it returns). Therefore the PM
(since a early fixpack in WARP4  (FP 17 in WARP3) can continue with serving
the system message queue.

 JdBP>   The synchronous nature of the "Synchronous Input Queue"

Grrr, its correct name is SYSTEM MESSAGE QUEUE. 

 JdBP> problem is not that the raw input queue is locked.  It *isn't*
 JdBP> locked once WinGetMsg() has returned (PM returns to the
 JdBP> application, not the other way around, by the way.) and the
 JdBP> application is deciding what to do with the message that it has
 JdBP> obtained.  

The technique PM functions is truly reverse. The redbook described it as
'reverse function call. This means that the PM controls the application
simplified as main() controls any funtion of a C program.

 JdBP> The synchronous nature of the SIQ problem is that focus change
 JdBP> processing is synchronous.  (I admit that I wasn't too clear
 JdBP> about this in my previous message. But this isn't the OS2PROG
 JdBP> echo where one normally goes into this sort of detail.) All of
 JdBP> the WM_ACTIVATE, WM_FOCUS, and WM_SETSELECTION messages that
 JdBP> result from WinFocusChange() are sent synchronously, as if by
 JdBP> WinSendMsg().  This means that the focus change will block
 JdBP> partway through changing the focus if one of the currently
 JdBP> active windows isn't calling WinGetMsg() frequently, or at all.
 JdBP>  (You'll notice that you'll never see a known "bad" application
 JdBP> lock Presentation Manager if you never give it the input focus
 JdBP> or make any of its windows active.)  

You have to differ between messages posted/send by an applications window and 
the ones sent by PM resulting from system message queue. You can simply go out 
blocking the system message queue by POSTING all longer actions to youself or
another thread. The point is the message received from system message queue
must return berfore another can go from it.

 JdBP> The "desynchronisation" fix in OS/2 Warp is to modify
 JdBP> WinFocusChange() so that the message sending will time out
 JdBP> after a fixed period.  (There's no timeout parameter to
 JdBP> WinSendMsg() so it must be using an internal, not publically
 JdBP> accessible, function to do this.)  If a thread refuses to
 JdBP> process and acknowledge a WM_ACTIVATE, WM_SETSELECTION, or
 JdBP> WM_SETFOCUS message within that time, WinFocusChange() simply
 JdBP> acts as if the message *had* been acknowledged, and also marks
 JdBP> the offending (WC_FRAME) window as "unresponsive" (and paints a
 JdBP> border around it) in case the same thing were to happen in the
 JdBP> future.

A window that dosn't own the focus can't receive any message from system
queue. Bercaus PM sends this only to a window that owns the focus - or has to
own after the focus change sequence (its an atomic sequence) is done.

You can freeze the PM with any message that comes from the system message
queue. Write a simple PM program and let it never return from a WM_CHAR - and
the PM hangs - until the syncronous timer in PM removes it (the app) from
system message queue.

Use the simple

WM_CHAR:
	while (1) sleep(10000);

to do it. You my act on a single key of your choce or whatever. Use a telnet
session to break the loop.


--- Sqed/32 1.15/development  45:
231/992
* Origin: Speed Kills - Use Windows! (2:2476/493)

SOURCE: echoes via The OS/2 BBS

Email questions or comments to sysop@ipingthereforeiam.com
All parts of this website painstakingly hand-crafted in the U.S.A.!
IPTIA BBS/MUD/Terminal/Game Server List, © 2025 IPTIA Consulting™.