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