Hello Sebastian,
I committed a simple change which corrects the problem by
enclosing the unload handler in a try/catch block.

I don't think this was a good idea. More interesting is the real place which leads to this error. A try/catch around the unload handler will also hide many other stuff. And in this case it also just hides the problem. If the unload handler will completely stopped after this error this would mean that the dispose process was stopped, too. This can be a reason of
Not exactly: the exception does not stop the main dispose process, for the
simple reason that  the dispose process has already ended, and this is
indeed the reason the exception is raised!

The unload handler of the log window only calls the closeWindow() method
of its windowAppender: but  in IE6, when this happens during
application unload, the windowAppender has already been freed, so the
try/catch simply traps this.

I understand it's perhaps a bit involved, so i'll try to explain it
better using a time diagram of what happens in FireFox, Opera and IE6.

This is what happens in FireFox (I hope the fixed-width font layout doesn't get
upset):

|->[main window].unload()
.   |
.   |->Init._onunload()
.   .   |
.   .   |->Object.dispose()
.   .   .   |
.   .   .   |->windowAppender.dispose()
.   .   .   .   |
.   .   .   .   |->windowAppender.closeWindow()
.   .   .   |<--|
.   .   |<--|
.   |<--|
|<--|
|
| {logWindow closes}
|->logWindow.unload()
.   |
.   |->windowAppender.closeWindow()
.   .   | {since this._logWindow == null, there is no action}
.   |<--|
|<--|
|
| {qx objects freed}
| {new document loads}
-


As you can see, closing the log window and calling its unload
handler is deferred till the end of the unload handler of the
application window; _javascript_ objects get properly freed after the log
window has been freed since it holds a reference to the qx object.

Let's see how Opera works:

|->[main window].unload()
.   |
.   |->Init._onunload()
.   .   |
.   .   |->Object.dispose()
.   .   .   |
.   .   .   |->windowAppender.dispose()
.   .   .   .   |
.   .   .   .   |->windowAppender.closeWindow()
.   .   .   .   .   this._logWindow.close()
.   .   .   .   .   |->logWindow.unload()
.   .   .   .   .   .   |
.   .   .   .   .   .   |->windowAppender.closeWindow()
.   .   .   .   .   .   .   | {repeated this._logWindow.close(), no effect}
.   .   .   .   .   .   |<--|
.   .   .   .   .   |<--|
.   .   .   .   |<--| {logWindow closes}
.   .   .   |<--|
.   .   |<--|
.   |<--|
|<--|
|
| {qx objects freed}
| {new document loads}
-

Opera closes the log window synchronously with the close() call, so
no problems here: the only slight anomaly is that the close() method of
the log window gets called a second time inside the close handler, but
since the window is already closing, this makes no harm. We could
enhance this by setting this._logWindow to null before calling close(), but
overall all works quite well.

Now to Internet Explorer 6; this is what I think happens based
on the observed behavior:

|->[main window].unload()
.   |
.   |->Init._onunload()
.   .   |
.   .   |->Object.dispose()
.   .   .   |
.   .   .   |->windowAppender.dispose()
.   .   .   .   |
.   .   .   .   |->windowAppender.closeWindow() ===> {msg to logWindow thread}
.   .   .   |<--|                                  | {logWindow thread awakened}
.   .   |<--|                                      |
.   |<--|                                          | {logWindow closes}       |<--|                                              |->logWindow.unload()
|                                                  .   |->windowAppender.closeWindow()
| {qx objects freed}                               .   .   |
|                                                  .   .   | {Exception: Unable to execute code from a freed script}
| {new document loads}                                     -
-

This has some resemblance the script loading problem  we are discussing
the XHTML compatibility thread: it seems IE6 handles closing of the log
window in an asynchronous way. But this should still work: the problem
here is that the qx object it gets freed during the execution of the close
handler, despite the fact that the log window still holds a reference to it.
To me this appears as a bug in the garbage collector of IE6.

memory leak. We should definitely find another solution here.

The ideal solution would be to wait for the log window to really close before
proceeding in the dispose method of WindowAppender. But, correct me
if I'm wrong, in _javascript_ there is no way to suspend waiting for something.

After all, the try/catch solution isn't that bad in my opinion. I agree that
it could hide real errors in the closeWindow() method when called from
the unload handler (for example if you manually close the log window)
but closeWindow() is so simple that I don't see this as a big problem.

Anyway, if you don't like the use of try/catch, I've thought of another
possible solution: we could force this._logWindow.qx to null when the
closeWindow() method is called from dispose(), and only execute the
unload handler if qx is not null, thus avoiding the call which raises the
exception at all: what do you think about this?

Cheers,
Alessandro


begin:vcard
fn:Alessandro Sala
n:Sala;Alessandro
email;internet:alessandro {dot} sala {at} mclink {dot} net
version:2.1
end:vcard

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
qooxdoo-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/qooxdoo-devel

Reply via email to