TIP: Click on subject to list as thread! ANSI
echo: os2prog
to: IVAN TODOROSKI
from: Herbert Rosenau
date: 1998-12-08 16:55:34
subject: the PM message queue

Hi IVAN,

 you wrote at 23.11.98  22:46 to DENIS TONN:
 
IT>>>    I have heard that this is because the PM has a single
IT>>> serialized    message queue for all applications, and no
IT>>> application can receive    messages while another is processing
IT>>> its message. A solution to    this would be multiple
IT>>> asynchronous message queues for each    application.

No. There is ONE system message queue but each PM application, exactly each
PM thread has its own message queue. The system message queue is the entry
point of system events such as mouse movements and keys, keyboard, timer.
This message queue is serialised because the event must find its correct
target in the 3 dimensonal PM world. If one event is sent to an window the
PM has to wait for its result (minimum: processing done) before it can
determine the correct receiver of the next message. So it blocks the
reading from the system message queue until the active message returns.
Other messages sent from an window to itself or another can and is handled
in a parallel way. 

 IT>   What I don't understand is this: if the PM sent a message to a
 IT> window   with WinPostMsg, the call to this API would return
 IT> immediately. How   would the PM receive the return value from the
 IT> message then?

Oups. You must differ between a window and the system message queue. The PM
itself (the instance sending messages from system queue to the target
window) has to wait for each message to serialise the events in a correct
way. The PM as the (default) instance of a window my send or post messages
depending on message type. Each window procedure is a callback routine of
of PM.

A little bit simplified description:

WinInitialise()		-> hey PM I'm living (1)
WinCreateMsgQueue() 	-> hey PM make room to receive messages for me (1)
WinGetMessage()		-> hey PM I have nothing to do exept you has
			   a message for me, if you have get it else
			   let me sleep (1)
WinDispatchMessage()	-> hey PM in my message queue is a message, send it to
			   the right window (1)
WinRegisterClass()	-> hey PM I will have a new window class, note the
			   receiver for all messages for that class. (1, 2)
WinCreate(Std)Window()/
WinCreateDlg()/
WinLoadWindow()		-> create the window as described and insert the given/
			   default procedure as receiver of messages associated
			   to that window (2)
WinSubclassWindow()	-> hey PM, I will receive all messages for the given
			   window class, don't send the messages to original
			   window procedure but to the given receiver. (1,2)
WinSendMsg()		-> SENDER must own a message queue; synchron (2,3)
WinPostMsg()		-> RECEIVER must own a message queue; asynchron (2,4)

1) thread spezific
2) system wide
1,2) depends on actual parameter
3) message is bufferd in senders message queue and dispatched directly while
   the actual message holds. So you my stay multiple times in the same window   
   procedure at the same time (1 x running, n x holding)
   similar to an (recursive) call of a subroutine
4) message is send into receivers message queue. The receiver will receive the
   message
   - after the actual message returns
     (WinGetMsg() in message loop) if the receiver is on the same thread
   - immediatly if it is another thread and it becomes CPU
   
Under NO CIRCUMSTANCE you should use global or static variables in your
message handling except you *_know_* *_exactly_* what you are doing. Use
Windowwords instead!

 IT>   Let's say the PM sent a WM_ERASEBACKGROUND message to a window
 IT> via   WinPostMsg. The window has to respond with TRUE or FALSE,
 IT> depending on   whether it wants its background redrawn or not.
 IT> But the WinPostMsg   call would return immediately, without
 IT> waiting for the window to   respond. How and when will the PM get
 IT> the reply from the window, and   erase (or not erase) its
 IT> background?

PM does NOT send this message. Only a (default) message procedure of a
window sends this. Don't mix up PM as task and PM as a system defined
window procedure.
A system defined window procedure is the same as a user definded except
that it is known systemwide per default.

A POSTed message never returns. There is no way to know the message was
successfull or not. The only result of a POST operation is: message is
successfull posted - or not. Because WinPostMsg() returns immediatly after
the message is queued into receivers message queue or the queueing is
impossible.

A SENDed message returns only if it is
- impossible to send
- the message returns from its associated window procedure.

 IT>   Well I got kind off interested in this, and decided to grep the
 IT> whole   \OS2\DLL directory for the string "winpostmsg", and found
 IT> that this   function is mentioned in PMWIN.DLL.

Nope. pmwin.dll is only a wrapper into pmmerge.dll.

If you patch the entry point in a dll *all* calls to that function are
changed! So if you change WinSendMsg to WinPostMsg *all*, truly *all*
messages are posted not sended and therefore most of message handling are
broken. NOTHING will work because most of SENDED messages gives results the
sender waiting for. Most of PM APIs are wrappers to messages with or
without other functionality.

On the other hand all messages are at least calls of window procedures.
There is no static definition which window procedure is to call for which
message. It's always dynamic and my change at runtime. See
WinSubclassWindow() an WinDispatchMsg() for details.

You my find in PMSHELL.EXE (instance 1) the point where system messages are
send. But any change there would be result in a dead system.

IT>>>   Is there a patch, a FixPak or a workaround that would fix
IT>>> this, or is   there a third party solution which can make the PM
IT>>> use multiple   asynchronous queues?

 DT>>  It would take a fairly major change to PM (and other parts of
 DT>> the system, WPS is a prime example) to implement. You would also
 DT>> break any apps that depend on the sync model (all the examples I
 DT>> know of are from corporate custom apps).

 IT>   But what about simple single window - single queue
 IT> applications? If I   understood correctly your explanation above,
 IT> they should be   unaffected, right?

No. PMSHELL.EXE is a server for windows. A window is described as a
rectange with an associated funtion. This window my or my not conain
another window........

The PM world is 3 dimensional. Each window resides on this 3D world.

x  = left corner
y  = lower corner
z  = foreground, background...

cx,cy width, hight.

You'll find *only* windows on your PM screen (yes, the background of WPS
*is* a simple window!). The blank PM screen (without WPS) is itself a
window too. So you'll have a lot of windows without running any PM programm
if PM (pmshell instance 1) is started and much more if WPS (pmshell
instance 2) lives.

Tschau/Bye

Herbert


--- Sqed/32 1.14/development  74:
* Origin: Was heute nicht richtig ist, kann morgen falsch sein (2:2476/493)
SEEN-BY: 396/1 632/0 371 633/260 267 270 371 635/444 506 728 639/252 670/218
@PATH: 2476/493 480 2410/200 2432/200 2433/1200 225 270/101 396/1 633/260
@PATH: 635/506 728 633/267

SOURCE: echomail via fidonet.ozzmosis.com

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™.