thecloud@dhw68k.cts.com (Ken McLeod) (10/05/88)
In article <882@hub.ucsb.edu> steveg@squid.ucsb.edu (Steve Greenland) writes: >I've come across an interesting bug involving Moire 2.12 (recently >posted to comp.binaries.mac) and MS Word 3.02. If you are in the >"Page Preview" mode of Word and Moire is activated (either through >timeout or by putting the mouse cursor in the upper right corner of >the screen), when you try to go back to Word, the system will crash. >Any modifications since the last save will be lost. > >My system is a Mac II, System 6.00, 1 Meg of memory. I have also had this occur, and I think it may actually be a problem with WaitNextEvent being implemented in System 6.0x all the time. The de-activation of Moire was causing my program under development to crash, so I tracked down the cause: Moire works by putting up its own window (the size of the screen) in front of all others, then paints it black. When it deactivates, this window goes away, and windows underneath it must be redrawn. Most Macintosh applications now call WaitNextEvent if it is implemented, and upon getting an event (in this case, an UpdateEvt), branch to an appropriate function to deal with it. Generally, the message field of the event is passed to a "doUpdate" function, which treats it as a pointer to the window that needs updating. Normally, if a program is NOT running under MultiFinder, we can expect that any UpdateEvt's given to us by GetNextEvent/WaitNextEvent are for our application's windows only (read: windows our application is responsible for drawing). Therefore, we SHOULD be able to assume that the message field of the event is a valid WindowPtr to one of "our" windows, and if GetNextEvent gives us the event, that's true. However, when WaitNextEvent gives us the event in the non-MF System 6.0x world, that isn't true anymore (I don't think). Anyway, one of the first things that a "doUpdate" function usually does, upon receiving the pointer to a window to be updated, is call the toolbox routine BeginUpdate(theWindowPtr). If "theWindowPtr" is not valid, we die! Pow! Restart! It appears that somehow we are getting an "event" to update Moire's window! But the window is gone, and the pointer is therefore invalid. The solution (obviously) is to check the pointer's validity before calling BeginUpdate() with something like this: if (!(theWindowPtr == myWindowPtr)) { /* we're in trouble */ } else { BeginUpdate(theWindowPtr); /* redraw the window */ EndUpdate(theWindowPtr); } Apparently MS Word's code doesn't do this (hey, neither did mine, at first), but then again, it isn't expecting to have to update windows other than its own! And curiously enough, everything is just fine when you run under MF; the program never receives the "extra" window update event when Moire is deactivated. So here's my question: is this a bug in the way WaitNextEvent has been implemented for UniFinder in 6.0.x? Or am I experiencing symptoms of increasing density? :-( (Sorry about the length, and overuse of the words "we" and "us" :-)) -ken -- ========== ....... =========================================== Ken McLeod :. .: uucp: {spsd, zardoz, felix}!dhw68k!thecloud ========== :::.. ..::: InterNet: thecloud@dhw68k.cts.com //// ===========================================
lsr@Apple.COM (Larry Rosenstein) (10/07/88)
In article <12606@dhw68k.cts.com> thecloud@dhw68k.cts.com (Ken McLeod) writes: > >responsible for drawing). Therefore, we SHOULD be able to assume that >the message field of the event is a valid WindowPtr to one of "our" >windows, and if GetNextEvent gives us the event, that's true. However, >when WaitNextEvent gives us the event in the non-MF System 6.0x world, >that isn't true anymore (I don't think). If you are not running MultiFinder, then windows are either your windows or DA windows. The system doesn't distinguish windows created by INIT code such as Moire. > It appears that somehow we are getting an "event" to update Moire's >window! But the window is gone, and the pointer is therefore invalid. >The solution (obviously) is to check the pointer's validity before >calling BeginUpdate() with something like this: > if (!(theWindowPtr == myWindowPtr)) { /* we're in trouble */ } This can be impractical if your application supports many windows. It sounds like a bug in Moire to me. It seems to be relying on some feature that is not true in this particular situation. It really should be preventing this problem by intercepting update events directed to its window so that they never get to the application. It is doing tricky things behind the application's back, so it has to be responsible for makin the application happy. Larry Rosenstein, Object Specialist Apple Computer, Inc. 20525 Mariani Ave, MS 46-B Cupertino, CA 95014 AppleLink:Rosenstein1 domain:lsr@Apple.COM UUCP:{sun,voder,nsc,decwrl}!apple!lsr
jkjl@munnari.oz (John Lim) (10/10/88)
In article <18342@apple.Apple.COM>, lsr@Apple.COM (Larry Rosenstein) writes: > In article <12606@dhw68k.cts.com> thecloud@dhw68k.cts.com (Ken McLeod) writes: > > > >responsible for drawing). Therefore, we SHOULD be able to assume that > >the message field of the event is a valid WindowPtr to one of "our" > >windows, and if GetNextEvent gives us the event, that's true. However, > >when WaitNextEvent gives us the event in the non-MF System 6.0x world, > >that isn't true anymore (I don't think). > > If you are not running MultiFinder, then windows are either your windows or > DA windows. The system doesn't distinguish windows created by INIT code > such as Moire. > Moire's window is a psuedo-DA window in the sense that the windowKind field is mapped to the moire driver. Thus i dont examine every event to see if it is for moire explicitly. I let the os pass all da events to me. > > It appears that somehow we are getting an "event" to update Moire's > >window! But the window is gone, and the pointer is therefore invalid. > >The solution (obviously) is to check the pointer's validity before > >calling BeginUpdate() with something like this: > > if (!(theWindowPtr == myWindowPtr)) { /* we're in trouble */ } > > This can be impractical if your application supports many windows. > Hypothesis : Still to be confirmed. ---------- The story gets complicated now. There is a feature in MF that causes it to give more time to DAs when update events are ignored. Moire 1.41 correctly handled update events, but performance in the Finder layer of MF was terrible because das are 10th class citizens under Finder in MF. Thus the fix was to refuse to clear the updateRgn, and thus performance of Moire improved as the os gave more time to moire in the form of additional update events. This Moire 2.1 refusal to handle update events must be confusing the os (and me). Because there are 3 ways to get events, GetNextEvent, EventAvail, and WaitNextEvent, the event handling mechanism might get out of synch. For example Moire closes a window because it detects mouse movement. This is done by patching getNextEvent. Meanwhile, WaitNextEvent is called by the application. WaitNextEvent is not in synch with GetNextEvent, and passes the old update event to the application, with the message field pointing to an invalid window. Conversely, if the application had called GetNextEvent, everything would probably be fine because i closed the window in a getnextevent patch, so the next call by Word or whatever to GNE would be in synch. Remember this is a hypothesis which i just cooked up while typing this in. I have to test it at home, but i'm 80% confident that that is what has been happening. Strangely enough, this bug only occurs in UniFinder, not in MF as you would expect. If anyone understands what i just said, congrats... It's so complicated because of bugs in applications that i have to work around, while still attempting to be a friendly guest of the host os. > It sounds like a bug in Moire to me. It seems to be relying on some > feature that is not true in this particular situation. It really should be > preventing this problem by intercepting update events directed to its window > so that they never get to the application. It is doing tricky things behind > the application's back, so it has to be responsible for makin the > application happy. > Quite right, larry. I've covered my ass in two ways now in Moire 2.2. (1). I explicitly check for Finder now. When i'm in the Finder layer, i ignore update events. In other layers, i obey update events like normal. Fortunately, normal applications give moire sufficient time to run - why doesnt finder ???? (2). I explicitly check the update events now. If the message is an invalid pointer, I correct the pointer. > Larry Rosenstein, Object Specialist > Apple Computer, Inc. 20525 Mariani Ave, MS 46-B Cupertino, CA 95014 > AppleLink:Rosenstein1 domain:lsr@Apple.COM > UUCP:{sun,voder,nsc,decwrl}!apple!lsr John Lim ps : i suspect that moire will break when we get real os with memory protection and pre-emptive multitasking. I makes me depressed to think that all our long messages and hard work will come to naught when Juggler/2 comes out ;-(