[net.micro.mac] Event queue questions

brian@ut-sally.UUCP (Brian H. Powell) (05/26/85)

     I am considering writing a desk accessory that will have to post items
on the event queue.  I suspect there will be a problem in filling up the
event queue.  There seems to be no means of finding out if the event queue
is full.  (PostEvent just discards the oldest event and posts the new event.
This means there is a good chance events will be lost.)
     The only solution I envision is for the desk accessory to slow down and
only post events when there is room.  So how do I find the size of the queue?
The only solution to this seems to be to traverse the queue, counting the
events.  (Is there a better way?)
     In Pascal, there is a "function GetEvQHdr : QHdrPtr; [Pascal only]"
which returns a pointer to the event queue.  I am using assembly.
Inside Mac says:
  "To access the contents of the event queue from assembly language, you can
use offsets from the address of the global variable EventQueue."
Umm, offsets?  Apparently this isn't just a pointer to the event queue.  (or
is it?)  IM doesn't say what kind of structure it is.  Can anybody elucidate?


Brian H. Powell      brian@ut-sally.{ARPA,UUCP}

		 U.S. Mail:		 Southwestern Bell
		P.O. Box 5899		451-0739
		Austin, TX 78763
					 AT&T
					(512) 451-0739

spector@acf4.UUCP (David HM Spector) (05/28/85)

 I believe that the structure of the queue entries is also defined in the event
manager quide as something to the effect of:


	Type EventRecord = RECORD
		What : 	Integer; {Event Code}
		Message:LongInt; {Event Message}
		When :	LongInt; {ticks since startup}
		Where:	Point;	 {Mouse Location}
		modifiers: Integer; {Modifier Flags}
	 End;

The OS Event Manager gives the type for the OS Event queues, and I think that
just chasing the qLink until you find NIL will tell you how many elents the
queue containes.

				Dave Spector
				NYU/acf Systems Group

steve@anasazi.UUCP (Steve Villee) (05/31/85)

> 
>      I am considering writing a desk accessory that will have to post items
> on the event queue.  I suspect there will be a problem in filling up the
> event queue.  There seems to be no means of finding out if the event queue
> is full.  (PostEvent just discards the oldest event and posts the new event.
> This means there is a good chance events will be lost.)
>      The only solution I envision is for the desk accessory to slow down and
> only post events when there is room.  So how do I find the size of the queue?
> The only solution to this seems to be to traverse the queue, counting the
> events.  (Is there a better way?)
>      In Pascal, there is a "function GetEvQHdr : QHdrPtr; [Pascal only]"
> which returns a pointer to the event queue.  I am using assembly.
> Inside Mac says:
>   "To access the contents of the event queue from assembly language, you can
> use offsets from the address of the global variable EventQueue."
> Umm, offsets?  Apparently this isn't just a pointer to the event queue.  (or
> is it?)  IM doesn't say what kind of structure it is.  Can anybody elucidate?
> 
> 
> Brian H. Powell      brian@ut-sally.{ARPA,UUCP}
> 
> 		 U.S. Mail:		 Southwestern Bell
> 		P.O. Box 5899		451-0739
> 		Austin, TX 78763
> 					 AT&T
> 					(512) 451-0739

     The following is a summary of the OS Event Manager data structures
as I understand them.  Some of this is documented in Inside Macintosh;
the rest is gleaned from a ROM disassembly.  The unfortunate bottom line
is that about the only way to do what you want to do is to duplicate the
code for PostEvent (starting at $40377C), but handle the case of queue
overflow correctly.

     The global variable SysEvtBuf = $146 is a pointer to an array of
event queue elements (type EvQEl shown on page 8 of the OS Event Manager
Manual).  Each such element is a 22 byte record, and the number of
elements is a configuration parameter (from location $7C of startup disk
sector 0), 20 by default.  This number minus 1 (for the convenience
of DBcc instructions) is stored in the global variable EvtBufCnt = $154.
An event queue element is marked as free (available for use by PostEvent)
by having $FFFF in its evQWhat component.  This is convenient because
all of memory is initially set to $FFFF.

     EventQueue = $14A is itself a 10 byte queue header, of type QHdr.
So the pointer to the first (oldest) item in the queue, if any, is at $14C.

     PostEvent does a linear scan through the array of event queue elements,
looking for a free one.  If they are all busy, it just commandeers the
first (oldest) one.  After loading the record with appropriate data,
it links it to the back of EventQueue.  All this is done with at least
VIA (level 1) interrupts disabled.  (Fortunately, I don't think SCC
interrupt handlers ever do PostEvent.)

     Anyway, yes, you can get a rough idea of how full the event queue
is, either by following the event queue itself or by linearly scanning
the array of event queue elements.  But in order to be really sure you
never destroy an old event, you need to disable interrupts, and at that
point you may as well just duplicate the PostEvent code, which is all
of 40 instructions.  I don't see how to do it using documented
procedures.

     Apple Flame: Personally, I think this business of just commandeering
the oldest event queue element when the queue overflows, without any
notice, is really bad.  It reminds me of what Unix tty drivers do when
input characters come in a little too fast.  It would have been so easy
to have PostEvent return an error result code in this case.  Then, if
the caller wanted to respond to this error by doing a GetOSEvent and
then retrying the PostEvent, he could.  But at least there would be
a documented way to do it right.


--- Steve Villee (asuvax!anasazi!steve)
    International Anasazi, Inc.
    2219 East University Drive
    Phoenix, Arizona 85034
    (602) 275-0302