9 Commits

Author SHA1 Message Date
edburns%acm.org
e77c9b9105 The problem was in the way the
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
2000-04-03 04:32:27 +00:00
edburns%acm.org
5345939064 Adding this line to the top of the run() method in
NativeEventThread seems to fix the hanging problem.

    this.setPriority(Thread.MIN_PRIORITY);


Looks like it was starvation.


git-svn-id: svn://10.0.0.236/trunk@64830 18797224-902f-48f8-a5cc-f745e15eee43
2000-04-01 01:17:33 +00:00
edburns%acm.org
f4d7081311 This checkin adds API to cleanly destroy a BrowserControl instance. It
also modifies EmbeddedMozilla so this code is exercised.

I have changed EmbeddedMozilla to be a stub-like class that simply
displays a Frame with a single Button, titled "New Window".  Pressing
this button causes an EMWindow to be created and displayed.  EMWindow is
basically the former EmbeddedMozilla renamed, with modifications to the
WindowListener implementation to call the BrowserControl deallocation
method.

I've added a delete() method to ImplObect:

 * I know Java has automatic garbage collection and all, but explicitly
 * adding a delete method helps the gc algorithm out. <P>

 * Subclasses should override this and call super.delete() at the end of
 * their overridden delete() method.

 * @see org.mozilla.webclient.wrapper_native.ImplObjectNative#delete

and ImplObjectNative:

 * Note how we call super.delete() at the end.  THIS IS VERY IMPORTANT. <P>

 * Also, note how we don't de-allocate nativeWebShell, that is done in
 * the class that owns the nativeWebShell reference, WindowControlImpl.

 * ImplObjectNative subclasses that further override delete() are <P>

<CODE><PRE>
BookmarksImpl.java
EventRegistrationImpl.java
NativeEventThread.java
WindowControlImpl.java
</PRE><CODE> <P>

 * All other ImplObject subclasses don't have any local Ivars and thus
 * don't need to override delete().

I've added a delete() method to BrowserControlImpl:

 * Called from BrowserControlFactory.deleteBrowserControl() <P>

 * The order of deletion of objects is very important! <P>

 * We don't allow deletion if the Canvas is showing. <P>

In BrowserControlImpl's delete(), the important delete()s is for
WindowControlImpl:

 * First, we delete our eventThread, which causes the eventThread to
 * stop running.  Then we call nativeDestroyInitContext(), which
 * deallocates native resources for this window.

As stated above, NativeEventThread.delete() is called:

 * This is a very delicate method, and possibly subject to race
 * condition problems.  To combat this, our first step is to set our
 * browserControlCanvas to null, within a synchronized block which
 * synchronizes on the same object used in the run() method's event
 * loop.  By setting the browserControlCanvas ivar to null, we cause the
 * run method to return.

After all of this deleting, we return from
BrowserControlFactory.delete().


git-svn-id: svn://10.0.0.236/trunk@62772 18797224-902f-48f8-a5cc-f745e15eee43
2000-03-13 18:44:32 +00:00
edburns%acm.org
c4a928699e r=ashuk
a=edburns
bug=31253

This change doesn't impact SeaMonkey.

Move the initialization of the nativeWebShell ptr into a superclass.


git-svn-id: svn://10.0.0.236/trunk@62501 18797224-902f-48f8-a5cc-f745e15eee43
2000-03-09 23:22:52 +00:00
ashuk%eng.sun.com
06ad7dc35e a=edburns
r=edburns
author=ashuk
bug=28407

Moved this file to java/webclient/classes_new/org/mozilla/webclient/wrapper_native -- Ashu K.


git-svn-id: svn://10.0.0.236/trunk@62344 18797224-902f-48f8-a5cc-f745e15eee43
2000-03-07 22:39:11 +00:00
ashuk%eng.sun.com
f746427b55 a=edburns
r=edburns
author=ashuk
bug=28407

New java code for spec-compliant impl ported to solaris -- Ashu K.


git-svn-id: svn://10.0.0.236/trunk@62337 18797224-902f-48f8-a5cc-f745e15eee43
2000-03-07 22:16:07 +00:00
ashuk%eng.sun.com
7c6e50cbd3 a=edburns
r=edburns
author=ashuk
bug=28407

New java code for spec-compliant impl ported to solaris -- Ashu K.


git-svn-id: svn://10.0.0.236/trunk@62336 18797224-902f-48f8-a5cc-f745e15eee43
2000-03-07 22:10:08 +00:00
ashuk%eng.sun.com
ccd51ccc8c a=edburns
r=edburns
author=ashuk
bug=28407

makefile for Java code - spec compliant impl -- Ashu K


git-svn-id: svn://10.0.0.236/trunk@62334 18797224-902f-48f8-a5cc-f745e15eee43
2000-03-07 22:03:57 +00:00
edburns%acm.org
530e00a191 a=edburns
r=ashuk
bug=2069

Java classes for spec compliant webclient impl.


git-svn-id: svn://10.0.0.236/trunk@62193 18797224-902f-48f8-a5cc-f745e15eee43
2000-03-04 01:10:58 +00:00