| TIP: Click on subject to list as thread! | ANSI |
| echo: | |
|---|---|
| to: | |
| from: | |
| date: | |
| subject: | the PM message queue |
Original from IVAN TODOROSKI to DENIS TONN on 11-23-1998
Original Subject: the PM message queue
---------------------------------------
IT>> I have heard that this is because the PM has a single serialized
IT>> message queue for all applications, and no application can receive
IT>> messages while another is processing its message. A solution to
IT>> this would be multiple asynchronous message queues for each
IT>> application.
DT> Take a look at the PM programmer's reference and pay particular
DT> attention to the above 2 API's. That is the core of the whole
DT> difference between a synchronous and an asynchronous design.
IT> I don't have the reference handy, since its gone with the hard disk
IT> (I'll have it after I reinstall the compilers), but I do remember
IT> reading about these two API functions, and if I recall correctly, they
IT> take the same arguments, and have the same return type.
IT>
IT> What I don't understand is this: if the PM sent a message to a window
IT> with WinPostMsg, the call to this API would return immediately. How
IT> would the PM receive the return value from the message then?
First, let me start with another couple of "cuts" from the Warp
debugging handbook:
----------------------------------
Non-PM application threads run in a relatively unconstrained
environment (compare this with the following situation).
The Operating System provides a black-box set of services and
interfaces.
The Hardware is not directly accessible by the application.
For PM message threads, the environment is radically different. The
key difference is that application code that runs on a PM message
thread is effectively a subroutine of the WinGetMsg API even though
WinGetMsg is called by the application. The terminology often used to
describe this reversal is Program Inversion. WinGetMsg is said to be
inverted with respect to the application's message thread.
PM Message threads act in a co-operative way. They wait for
messages, and pass them on to the appropriate application if not for
themselves.
PM Message threads should spend most of their elapsed time waiting
for notification of messages - because of their co-operative nature.
Application code that runs on the message thread should be limited
to very short duration processing. We often speak of the
tenth-of-a-second rule, which is intended to imply the transient
nature of application code processing rather than a precise measure.
If a message thread communicates with another thread or the
operating system, then this should be done either asynchronously or so
as not to violate the tenth-of-a-second rule.
PM messages are generated either as the result of user interaction
with the system or by the use of various PM APIs. Both PM and non-PM
applications may generate PM messages.
Messages may flow:
synchronously, that is, require processing by the recipient before
the sender can continue, or
asynchronously, that is, where no reposonse is required.
They may flow between threads (inter-thread messages) or from a
thread to itself (intra-thread messages). These characteristics
require a message queuing mechanism to be implemented so that message
order may be preserved.
Note: A message's meaning may often depend on the outcome of a
preceding message. For example, consider the action of the F4 key
after the Alt key has been pressed.
Each PM message thread has two queues or more strictly speaking a
message queue and a message list. There may be only one instance of
these two structures per thread.
The message queue is a circular array, the size of which is
specified or defaulted by the application when it creates the queue
using WinCreateMsgQueue.
This queue is used for the receipt of asynchronous messages generated
by use of the WinPostMsg API.
The message list has no depth and is created implicitly by
WinCreateMsgQueue. This is used for the receipt of synchronous
messages sent using WinSendMsg.
WinCreateMsgQueue also creates a message event semaphore that is
posted whenever a message, synchronous or asynchronous, is posted; or
a message response is generated. This is the semaphore on which
WinGetMsg waits for message notification.
There is a system queue, which is also a circular array. Messages are
enqueued on the system queue by the PMDD.SYS device driver as the
result of external events deriving directly from:
Mouse activity
Keyboard activity
Use of a light pen
Timer ticks.
PM maintains knowledge of who the current, mouse, keyboard, pen, and
event receivers are. When an external event causes a message to be
queued on the system queue, PM posts the message event semaphore of
the current receiver of that particular event.
An application may define Window Procedures - entry points within the
message thread. These are associated with a PM Window and a message
queue. They receive control when a message is dispatched, that is
dequeued from the message queue or message list. More than one window
procedure may be serviced by the same message queue/list. Which one
should be dispatched is determined from the HWND, which is one of the
parameters associated with a message.
When WinGetMsg receives a message event notification, it first checks
for the presence of received synchronous messages, if there are any
dispatches them directly. Next it looks for an application generated
(posted) message and finally for a system queue message.
The application thread explicitly dispatches asynchronous messages
using WinDispatchMsg.
The System Queue entries are SQMSG structures.
The Application Queue entries are QMSG structures.
The Application Send Message List comprises a chain of SMS structures.
----------------------------------
There are a few diagrams that goes along with this (but don't paste
well into a fido text message).
For "sent" messages, the WinGetMsg API drives the application's
thread sequentially (cooperatively) with the PM (or other
application's) thread that "sent" the message. For
"posted" messages,
the sem that WinGetMsg blocked on is simply posted (and thereby
"ready" for the scheduler). The actions performed by the code in the
WinGetMsg API is the same.
In either the stack would be setup to "return" through a path in PM
that would perform the action specified by the app's Window procedure
(or a default action if the app ignored PM's message).
DT> Sure it can. See the differences above between WinSendMsg and
DT> WinPostMsg. If you want to build a "front end" to all
the events (IE:
DT> your app needs to understand which underlying "app" the
event needs to
DT> be delivered to) you can deliver via WinPostMsg.
IT> Well I got kind off interested in this, and decided to grep the whole
IT> \OS2\DLL directory for the string "winpostmsg", and
found that this
IT> function is mentioned in PMWIN.DLL.
IT>
IT> I don't know anything about the structure of OS/2 DLL's, (and indeed
IT> about many other things internal to OS/2, but that's changing thanks
IT> to you :), but by looking at PMWIN.DLL with an ASCII editor that can
IT> show the ASCII value of the character under the cursor, I noticed that
IT> there are a bunch of API function names at the start of the DLL.
IT>
IT> Before every name there is a byte which holds the length of the name,
IT> and after every name there is a two-byte number which increases by one
IT> after each name (it is not always by one, there are some jumps, e.g.
IT> from 250 it jumps directly to 264), so I guess this is the ordinal
IT> number of the function in the DLL.
The ordinal number is the only thing used by the app or the loader.
IT> So, this must be the table for associating names with ordinal numbers
IT> and vice versa. Logic dictates that there must be some other table
IT> further in the DLL which associates ordinal numbers with entry points
IT> in the DLL, but I wasn't able to find anything like it due to the
IT> limitations of the tools I had to work with (basically an OS/2 port of
IT> the unix grep and the FTE editor)
Correct. There is a table that associates ordinal numbers with entry
points.
IT> This questions must seem very basic to you, but please bear with me.
IT> Some of you have used OS/2 for years, but only 6 months ago I didn't
IT> even know what OS/2 is, and thought of IBM as "this big company from
IT> the past"! I only became interested in OS/2 programming about 2 months
IT> ago, and only documents I had to learn from were the API reference
IT> (which is extremely dry, and just lists functions in alphabetical
IT> order without giving much information on how to use them best) and
IT> some examples from Hobbes. I managed to cover all of the base API and
IT> most of the PM API. I still have GPI, SOM and some other stuff left.
IT> Try to imagine what a shock this must be for a DOS programmer used to
IT> hooking interrupts and poking at MCB's (Memory Control Blocks)
IT> directly under DOS...
IT>
IT> Anyway, if this kind of table exists, wouldn't it be possible then to
IT> simply exchange the entry point pointers for WinSendMsg and WinPostMsg,
IT> thus forcing the PM to use WinPostMsg instead of WinSendMsg for sending
IT> messages?
Possible, yes. But WinGetMsg would then have to be run on a thread
initiated from the application side rather than a thread initiated
from PM.
IT> I know that this would probably make the system unbootable, but anyway,
IT> I would like to try this and see what breaks. Could you give some info
IT> on the DLL structure, or tell me where can I find some info?
IT> Downloadable form is prefered. :)
LxLite (which I gather you already have) can supply this information.
The developer's toolkit also includes a tool that will extract this
information - EXEHDR..
IT>> Is there a patch, a FixPak or a workaround that would fix this, or is
IT>> there a third party solution which can make the PM use multiple
IT>> asynchronous queues?
DT> It would take a fairly major change to PM (and other parts of the
DT> system, WPS is a prime example) to implement. You would also break
DT> any apps that depend on the sync model (all the examples I know of are
DT> from corporate custom apps).
IT> But what about simple single window - single queue applications? If I
IT> understood correctly your explanation above, they should be
IT> unaffected, right?
No. Simply swapping the API's doesn't work. I suggest you get the
debugging handbook and look at the diagrams that go along with the
above text. It might help to clear some things up (and probably
generate a LOT more questions).
Denis
All opinions are my very own, IBM has no claim upon them
.
.
.
--- Maximus/2 3.01
* Origin: T-Board - (604) 277-4574 (1:153/908)SEEN-BY: 396/1 632/0 371 633/260 267 270 371 635/444 506 728 639/252 670/218 @PATH: 153/908 8086 800 140/1 396/1 633/260 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™.