NativeEventThread's run() method's infinite loop was implemented. The
loop looks like this:
while (null != this.browserControlCanvas) {
synchronized (this.browserControlCanvas.getTreeLock()) {
nativeProcessEvents(nativeWebShell);
if (null != listenersToAdd && !listenersToAdd.isEmpty()) {
tempEnum = listenersToAdd.elements();
while (tempEnum.hasMoreElements()) {
nativeAddListener(nativeWebShell,
(WebclientEventListener)
tempEnum.nextElement());
}
listenersToAdd.clear();
}
}
}
The problem I was observing was that
nativeProcessEvents(nativeWebShell) would crash due to the fact that
the nativeWebShell, which is actually an WebShellInitContext instance,
had been de-allocated. This de-allocation happens as a result of the
WindowControlImpl.delete() method, which looks like this:
public void delete()
{
Assert.assert(null != eventThread, "eventThread shouldn't be null at delete time");
eventThread.delete();
eventThread = null;
nativeDestroyInitContext(nativeWebShell);
nativeWebShell = -1;
}
nativeDestroyInitContext de-allocates the WebShellInitContextInstance.
You can see that the first thing done is to delete the eventThread().
NativeEventThread.delete() looks like this:
public void delete()
{
// setting this to null causes the run thread to exit
synchronized(this.browserControlCanvas.getTreeLock()) {
browserControlCanvas = null;
}
...
}
If you compare NativeEventThread.delete() with the infinite loop in
NativeEventThread.run(), you'll see that the fact that they both
synchronize on the same object doesn't protect us from the following
case:
NativeEventThread: The infinite loop checks to see if the
browserControlCanvas is null, then does synchronize on
browserControlCanvas.getTreeLock(), then calls processNativeEvents().
meanwhile
WindowControlImpl thread: delete() calls NativeEventThread.delete(),
which does synchronize on browserControlCanvas.getTreeLock().
During NativeEventThread.delete(), synchronized section,
browserControlCanvas is set to null.
NativeEventThread: because the check for null browserControlCanvas
occurrs outside of the synchronized block, it's not recheked, and
thus, the event loop continues to process when it shouldn't.
The fix is to change the event loop to look like this:
while (true) {
synchronized (this.browserControlCanvas.getTreeLock()) {
// this has to be inside the synchronized block!
if (null == this.browserControlCanvas) {
return;
}
nativeProcessEvents(nativeWebShell);
if (null != listenersToAdd && !listenersToAdd.isEmpty()) {
tempEnum = listenersToAdd.elements();
while (tempEnum.hasMoreElements()) {
nativeAddListener(nativeWebShell,
(WebclientEventListener)
tempEnum.nextElement());
}
listenersToAdd.clear();
}
}
}
git-svn-id: svn://10.0.0.236/trunk@64998 18797224-902f-48f8-a5cc-f745e15eee43
Here lies the MozWebShell java wrapper to mozilla M8.
Authors: Kirk Baker <kbaker@eb.com>
Ian Wilkinson <iw@ennoble.co>
Build hacking and packaging: Ed Burns <edburns@acm.org>
Unix port: Mark Lin <mark.lin@eng.sun.com>
========================================================================
Win32 Build Directions:
========================================================================
Requirements:
* built mozilla with source code from after 10/5/99
* JDK1.1.7 or greater
* built org.mozilla.util java classes (see NOTE_UTIL)
* Perl 5 perl.exe must be in your path
How To Build:
* Follow the directions in ..\README
* type "nmake /f makefile.win all" and hope for the best
How to Run:
* once the build has successfully completed, run this batch file:
.\src\WIN32_D.OBJ\runem.bat <opt: YOUR_URL>
Note that YOUR_URL is probably necessary since firewall support wasn't
working in M8.
Problems:
* clobber_all doesn't remove the .class files from dist\classes. You
have to do this manually.
* post to netscape.public.mozilla.java newsgroup
========================================================================
Unix Build Directions (currently only Linux,
Solaris support is coming soon):
========================================================================
Requirements:
* built mozilla tree for some variant of Linux
* JDK1.2 with native threads support from http://www.blackdown.org
(JDK1.1 doesn't seem to work)
* built org.mozilla.util java classes (see NOTE_UTIL)
How To Build:
* Follow the directions in ../util/README
* set JDKHOME to where your JDK install directory resides
-> setenv JDKHOME /usr/local/jdk1.2
* cd to 'classes' and type "make -f makefile.unix" and hope for the best
-> cd classes; make -f Makefile.unix
* then cd to 'src' and type "make -f makefile.unix" and hope for the best
-> cd src; make -f Makefile.unix
How to Run:
* once the build has successfully completed, run 'runem.unix' in your
'src' directory:
-> cd src; ./runem.unix <YOUR_URL>
Note that YOUR_URL is probably necessary since firewall support wasn't
working in M8.
Problems? Email mark.lin@eng.sun.com or post to netscape.public.mozilla.java.
========================================================================
NOTE_UTIL:
========================================================================
* this package depends on the org.mozilla.util classes, which can be
found in the mozilla tree under mozilla\java\util. They are a
separate checkout and build. Once you check out the org.mozilla.util
classes, see the README in the mozilla\java\util\README.
General notes:
* Please update the ChangeLog (changelo) when you make changes.