M webclient/classes_spec/org/mozilla/webclient/impl/WrapperFactory.java

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

- cause the webclient native library to be loaded from the
  NativeEventThread.  This eliminates many native thread safety
  assertions.

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

- Initialize the dom on the NativeEventThread

- Get the dom on the NativeEventThread

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

- remove unnecessary synchronized block.
This commit is contained in:
edburns%acm.org 2007-03-09 17:25:48 +00:00
parent 8f8efb73fd
commit 3e802a732e
5 changed files with 72 additions and 40 deletions

View File

@ -51,6 +51,20 @@ public interface WrapperFactory {
public String getProfile();
public void setProfile(String profileName);
/**
*
* <p>This method must not be called by the developer.
*
* <p>Cause the native library to be loaded, if necessary. This method
* must be called from the native event thread.</p>
*
* <p>POSTCONDITION: Native library for webclient has been loaded.</p>
*
* @return implmentation specific native int.
*
*/
public int loadNativeLibraryIfNecessary();
/**
*
* <p>Cause the native library to be loaded, if necessary.</p>

View File

@ -87,7 +87,15 @@ public CurrentPageImpl(WrapperFactory yourFactory,
super(yourFactory, yourBrowserControl);
// force the class to be loaded, thus loading the JNI library
if (!domInitialized) {
DOMAccessor.initialize();
NativeEventThread.instance.pushBlockingWCRunnable(new WCRunnable() {
public Object run() {
DOMAccessor.initialize();
return null;
}
public String toString() {
return "WCRunnable.CurrentPageImpl ctor";
}
});
}
domDumper = new DOMTreeDumper();
}
@ -295,13 +303,24 @@ public String getCurrentURL()
public Document getDOM()
{
// PENDING(edburns): run this on the event thread.
Document result = nativeGetDOM(getNativeBrowserControl());
if (LOGGER.isLoggable((Level.INFO))) {
LOGGER.info("CurrentPageImpl.getDOM(): getting DOM with URI: " +
result.getDocumentURI());
}
return result;
final Document[] resultHolder = new Document[1];
resultHolder[0] = null;
NativeEventThread.instance.pushBlockingWCRunnable(new WCRunnable() {
public Object run() {
Document result = nativeGetDOM(getNativeBrowserControl());
if (LOGGER.isLoggable((Level.INFO))) {
LOGGER.info("CurrentPageImpl.getDOM(): getting DOM with URI: " +
result.getDocumentURI());
}
resultHolder[0] = result;
return null;
}
public String toString() {
return "WCRunnable.CurrentPageImpl.getDOM";
}
});
return resultHolder[0];
}
public Properties getPageInfo()

View File

@ -263,28 +263,26 @@ public void setNewWindowListener(NewWindowListener listener)
{
getWrapperFactory().verifyInitialized();
synchronized(this) {
final boolean doClear = null == listener;
NativeEventThread.instance.pushBlockingWCRunnable(new WCRunnable(){
public Object run() {
if (doClear) {
nativeSetNewWindowListenerAttached(getNativeBrowserControl(),
false);
}
else {
nativeSetNewWindowListenerAttached(getNativeBrowserControl(),
true);
}
return null;
}
public String toString() {
return "WCRunnable.nativeSetNewWindowListenerAttached";
}
final boolean doClear = null == listener;
NativeEventThread.instance.pushBlockingWCRunnable(new WCRunnable(){
public Object run() {
if (doClear) {
nativeSetNewWindowListenerAttached(getNativeBrowserControl(),
false);
}
else {
nativeSetNewWindowListenerAttached(getNativeBrowserControl(),
true);
}
return null;
}
public String toString() {
return "WCRunnable.nativeSetNewWindowListenerAttached";
}
});
newWindowListener = listener;
}
});
newWindowListener = listener;
}
/**

View File

@ -76,8 +76,7 @@ public class NativeEventThread extends Thread {
//
public NativeEventThread(String threadName,
WrapperFactory yourFactory,
int yourNativeWrapperFactory) {
WrapperFactory yourFactory) {
super(threadName);
// Don't do this check for subclasses
if (this.getClass() == NativeEventThread.class) {
@ -86,8 +85,6 @@ public class NativeEventThread extends Thread {
ParameterCheck.nonNull(yourFactory);
wrapperFactory = yourFactory;
nativeWrapperFactory = yourNativeWrapperFactory;
blockingRunnables = new ConcurrentLinkedQueue<WCRunnable>();
runnables = new ConcurrentLinkedQueue<Runnable>();
}
@ -142,6 +139,8 @@ public class NativeEventThread extends Thread {
public void run()
{
nativeWrapperFactory = wrapperFactory.loadNativeLibraryIfNecessary();
// our owner must have put an event in the queue
Assert.assert_it(!runnables.isEmpty());
((Runnable)runnables.poll()).run();

View File

@ -277,22 +277,24 @@ public class WrapperFactoryImpl extends Object implements WrapperFactory {
return profileName;
}
public int loadNativeLibraryIfNecessary() {
System.loadLibrary("webclient");
nativeWrapperFactory = nativeCreateNativeWrapperFactory();
Assert.assert_it(-1 != nativeWrapperFactory);
return nativeWrapperFactory;
}
public void initialize(String verifiedBinDirAbsolutePath) throws SecurityException, UnsatisfiedLinkError {
if (initialized) {
return;
}
System.loadLibrary("webclient");
//
// Do the first initialization call
//
nativeWrapperFactory = nativeCreateNativeWrapperFactory();
Assert.assert_it(-1 != nativeWrapperFactory);
eventThread = new NativeEventThread("WebclientEventThread", this,
nativeWrapperFactory);
eventThread = new NativeEventThread("WebclientEventThread", this);
final String finalStr = new String(verifiedBinDirAbsolutePath);