Skip to content

Commit

Permalink
M classes_spec/org/mozilla/webclient/impl/WrapperFactory.java
Browse files Browse the repository at this point in the history
M classes_spec/org/mozilla/webclient/impl/wrapper_native/EventRegistrationImpl.java
M classes_spec/org/mozilla/webclient/impl/wrapper_native/ImplObjectNative.java

- remove getNativeEventThread().  I've decided to expose the singleton
  NativeEventThread instance via a package private class var.

M classes_spec/org/mozilla/webclient/impl/wrapper_native/BookmarksImpl.java

- run the necessary native methods on the event thread to avoid thread
  safety assertions.

M classes_spec/org/mozilla/webclient/impl/wrapper_native/NativeEventThread.java

- rename pushNotifyRunnable() to pushBlockingWCRunnable.  Make it block
  the caller until the argument WCRunnable has been run on the
  NativeEventThread.  Implement this by using wait/notify between
  pushBlockingWCRunnable() and run().

- add package private NativeEventThread class variable.

- rename runnablesWithNotify ivar to blockingRunnables.

- remove the exception storage mechanism.

M classes_spec/org/mozilla/webclient/impl/wrapper_native/NavigationImpl.java
M classes_spec/org/mozilla/webclient/impl/wrapper_native/PreferencesImpl.java
M classes_spec/org/mozilla/webclient/impl/wrapper_native/ProfileManagerImpl.java
M classes_spec/org/mozilla/webclient/impl/wrapper_native/RDFEnumeration.java
M classes_spec/org/mozilla/webclient/impl/wrapper_native/WrapperFactoryImpl.java

- levarage NativeEventThread.instance.pushBlockingWCRunnable().

A classes_spec/org/mozilla/webclient/impl/wrapper_native/WCRunnable.java

- Just like runnable, except return Object, not void.

M src_moz/PreferencesImpl.cpp

- remove unused automatic variable.
  • Loading branch information
edburns%acm.org committed Apr 17, 2004
1 parent 2c3caf6 commit d45931d
Show file tree
Hide file tree
Showing 12 changed files with 332 additions and 206 deletions.
Expand Up @@ -77,6 +77,4 @@ public Object newImpl(String interfaceName,
*/

public int getNativeBrowserControl(BrowserControl bc);

public Object getNativeEventThread();
}
@@ -1,5 +1,4 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
Expand Down Expand Up @@ -77,10 +76,12 @@ public BookmarksImpl(WrapperFactory yourFactory)
}

public void startup() {
Assert.assert_it(isNativeEventThread());
nativeStartup(getWrapperFactory().getNativeWrapperFactory());
}

public void shutdown() {
Assert.assert_it(isNativeEventThread());
nativeShutdown(getWrapperFactory().getNativeWrapperFactory());
}

Expand Down Expand Up @@ -152,16 +153,24 @@ public TreeModel getBookmarks() throws IllegalStateException
getWrapperFactory().verifyInitialized();

if (null == bookmarksTree) {
int nativeBookmarks;
TreeNode root;
if (-1 ==
(nativeBookmarks =
nativeGetBookmarks(getWrapperFactory().getNativeWrapperFactory()))) {
Integer nativeBookmarks = (Integer)
NativeEventThread.instance.pushBlockingWCRunnable(new WCRunnable() {
public Object run() {
Integer result =
new Integer(nativeGetBookmarks(getWrapperFactory().
getNativeWrapperFactory()));
return result;
}
});

if (-1 == nativeBookmarks.intValue()) {
throw new IllegalStateException("BookmarksImpl.getBookmarks(): Can't get bookmarks from native browser.");
}
// if we can't create a root, or we can't create a tree
if ((null == (root = new BookmarkEntryImpl(getWrapperFactory().getNativeWrapperFactory(),
nativeBookmarks, null))) ||
nativeBookmarks.intValue(),
null))) ||
(null == (bookmarksTree = new DefaultTreeModel(root)))) {
throw new IllegalStateException("BookmarksImpl.getBookmarks(): Can't create RDFTreeModel.");
}
Expand All @@ -181,13 +190,23 @@ public void removeBookmark(BookmarkEntry bookmark)

public BookmarkEntry newBookmarkEntry(String url)
{
ParameterCheck.nonNull(url);
BookmarkEntry result = null;
final String finalUrl = new String(url);
getBookmarks();
int newNode;

if (-1 != (newNode = nativeNewRDFNode(getNativeBrowserControl(), url, false))) {
Integer newNode = (Integer)
NativeEventThread.instance.pushBlockingWCRunnable(new WCRunnable() {
public Object run() {
Integer result =
new Integer(nativeNewRDFNode(getNativeBrowserControl(),
finalUrl, false));
return result;
}
});

if (-1 != newNode.intValue()) {
result = new BookmarkEntryImpl(getNativeBrowserControl(),
newNode, null);
newNode.intValue(), null);
// use put instead of setProperty for jdk1.1.x compatibility.
result.getProperties().put(BookmarkEntry.NAME, url);
result.getProperties().put(BookmarkEntry.URL, url);
Expand Down
Expand Up @@ -81,7 +81,7 @@ public EventRegistrationImpl(WrapperFactory yourFactory,
super(yourFactory, yourBrowserControl);

// pull out the NativeEventThread from the WrapperFactory
nativeEventThread = getNativeEventThread();
nativeEventThread = NativeEventThread.instance;
}

public void delete()
Expand Down Expand Up @@ -265,7 +265,7 @@ public static void main(String [] args)

Log.setApplicationName("EventRegistrationImpl");
Log.setApplicationVersion("0.0");
Log.setApplicationVersionDate("$Id: EventRegistrationImpl.java,v 1.4 2004/04/15 22:58:06 edburns%acm.org Exp $");
Log.setApplicationVersionDate("$Id: EventRegistrationImpl.java,v 1.5 2004/04/17 21:25:11 edburns%acm.org Exp $");

try {
org.mozilla.webclient.BrowserControlFactory.setAppData(args[0]);
Expand Down
Expand Up @@ -99,9 +99,9 @@ protected int getNativeBrowserControl() {
return nativeWebShell;
}

protected NativeEventThread getNativeEventThread() {
return (NativeEventThread)
getWrapperFactory().getNativeEventThread();
protected boolean isNativeEventThread() {
return (Thread.currentThread() == NativeEventThread.instance);
}


} // end of class ImplObject
Expand Up @@ -47,7 +47,7 @@

/**
* <p>This is a singleton class. All native events pass thru this class
* by virtue of the {@link #pushRunnable} or {@link pushNotifyRunnable}
* by virtue of the {@link #pushRunnable} or {@link pushBlockingWCRunnable}
* methods.</p>
*/

Expand All @@ -56,18 +56,17 @@ public class NativeEventThread extends Thread {
//
// Class variables
//

static NativeEventThread instance = null;

//
// Attribute ivars
//

/**
* store the exception property, set when running a Runnable causes
* an exception.
*/
private Object blockingResult;

private Exception blockingException;

private Exception exception;

//
// Relationship ivars
//
Expand All @@ -77,7 +76,7 @@ public class NativeEventThread extends Thread {

private BrowserControlCanvas browserControlCanvas;

private Stack runnablesWithNotify;
private Stack blockingRunnables;
private Stack runnables;


Expand All @@ -93,12 +92,14 @@ public NativeEventThread(String threadName,
WrapperFactory yourFactory,
int yourNativeWrapperFactory) {
super(threadName);
Assert.assert_it(null == instance);
instance = this;
ParameterCheck.nonNull(yourFactory);

wrapperFactory = yourFactory;
nativeWrapperFactory = yourNativeWrapperFactory;

runnablesWithNotify = new Stack();
blockingRunnables = new Stack();
runnables = new Stack();
}

Expand Down Expand Up @@ -127,33 +128,18 @@ public void delete() {
wrapperFactory = null;
}

public Exception getAndClearException() {
synchronized (this) {
Exception result = exception;
exception = null;
}
return exception;
}

public void setException(Exception e) {
synchronized (this) {
exception = e;
}
}

//
// Methods from Thread
//

/**
* This method is the heart of webclient. It is called from
* {@link WrapperFactoryImpl#getNativeEventThread}. It calls
* nativeStartup, which does the per-window initialization, including
* creating the native event queue which corresponds to this instance,
* then enters into an infinite loop where processes native events, then
* checks to see if there are any listeners to add, and adds them if
* necessary.
* This method is the heart of webclient. It is called indirectly from
* {@link WrapperFactoryImpl#initialize}. It calls nativeStartup, which
* does the per-window initialization, including creating the native
* event queue which corresponds to this instance, then enters into an
* infinite loop where processes native events, then checks to see if
* there are any listeners to add, and adds them if necessary.
* @see nativeProcessEvents
Expand All @@ -164,7 +150,16 @@ public void setException(Exception e) {
public void run()
{
// our owner must have put an event in the queue
Assert.assert_it(!runnablesWithNotify.empty());
Assert.assert_it(!runnables.empty());
((Runnable)runnables.pop()).run();
synchronized (wrapperFactory) {
try {
wrapperFactory.notify();
}
catch (Exception e) {
System.out.println("NativeEventThread.run: exception trying to send notify() to WrapperFactoryImpl on startup:" + e + " " + e.getMessage());
}
}

//
// Execute the event-loop.
Expand Down Expand Up @@ -193,16 +188,32 @@ public void run()
if (!runnables.empty()) {
((Runnable)runnables.pop()).run();
}
if (!runnablesWithNotify.empty()) {
((Runnable)runnablesWithNotify.pop()).run();
synchronized(wrapperFactory) {
try {
wrapperFactory.notify();
}
catch (Exception e) {
System.out.println("NativeEventThread.run: Exception: trying to send notify() to wrapperFactory: " + e + " " + e.getMessage());
}
if (!blockingRunnables.empty()) {
try {
blockingException = null;
blockingResult =
((WCRunnable)blockingRunnables.pop()).run();
}
catch (RuntimeException e) {
blockingException = e;
}
// notify the pushBlockingWCRunnable() method.
try {
notify();
}
catch (Exception e) {
System.out.println("NativeEventThread.run: Exception: trying to notify for blocking result:" + e + " " + e.getMessage());
}
// wait for the result to be grabbed. This prevents the
// results from getting mixed up.
try {
wait();
}
catch (Exception e) {
System.out.println("NativeEventThread.run: Exception: trying to waiting for pushBlockingWCRunnable:" + e + " " + e.getMessage());
}


}
nativeProcessEvents(nativeWrapperFactory);
}
Expand All @@ -223,10 +234,32 @@ void pushRunnable(Runnable toInvoke) {
}
}

void pushNotifyRunnable(Runnable toInvoke) {
Object pushBlockingWCRunnable(WCRunnable toInvoke) {
Object result = null;
RuntimeException e = null;
synchronized (this) {
runnablesWithNotify.push(toInvoke);
blockingRunnables.push(toInvoke);
try {
wait();
}
catch (Exception se) {
System.out.println("NativeEventThread.pushBlockingWCRunnable: Exception: while waiting for blocking result: " + se + " " + se.getMessage());
}
result = blockingResult;
if (null != blockingException) {
e = new RuntimeException(blockingException);
}
try {
notify();
}
catch (Exception se) {
System.out.println("NativeEventThread.pushBlockingWCRunnable: Exception: trying to send notify() to NativeEventThread: " + se + " " + se.getMessage());
}
}
if (null != e) {
throw e;
}
return result;
}

/**
Expand Down
@@ -1,5 +1,4 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
Expand Down Expand Up @@ -85,13 +84,12 @@ public void loadURL(String absoluteURL)
final int bc = getNativeBrowserControl();
final String url = new String(absoluteURL);
Assert.assert_it(-1 != bc);

Runnable loadURL = new Runnable() {
public void run() {
NavigationImpl.this.nativeLoadURL(bc, url);
}
};
getNativeEventThread().pushRunnable(loadURL);

NativeEventThread.instance.pushRunnable(new Runnable() {
public void run() {
NavigationImpl.this.nativeLoadURL(bc, url);
}
});
}

public void loadFromStream(InputStream stream, String uri,
Expand Down Expand Up @@ -228,7 +226,7 @@ public static void main(String [] args)

Log.setApplicationName("NavigationImpl");
Log.setApplicationVersion("0.0");
Log.setApplicationVersionDate("$Id: NavigationImpl.java,v 1.4 2004/04/15 22:58:06 edburns%acm.org Exp $");
Log.setApplicationVersionDate("$Id: NavigationImpl.java,v 1.5 2004/04/17 21:25:11 edburns%acm.org Exp $");

try {
org.mozilla.webclient.BrowserControlFactory.setAppData(args[0]);
Expand Down

0 comments on commit d45931d

Please sign in to comment.