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

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.
This commit is contained in:
edburns%acm.org 2004-04-17 21:25:12 +00:00
Родитель 2db4e18cdf
Коммит d16514e53c
12 изменённых файлов: 333 добавлений и 207 удалений

Просмотреть файл

@ -77,6 +77,4 @@ public interface WrapperFactory {
*/ */
public int getNativeBrowserControl(BrowserControl bc); 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 * The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file * License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of * except in compliance with the License. You may obtain a copy of
@ -77,10 +76,12 @@ public BookmarksImpl(WrapperFactory yourFactory)
} }
public void startup() { public void startup() {
Assert.assert_it(isNativeEventThread());
nativeStartup(getWrapperFactory().getNativeWrapperFactory()); nativeStartup(getWrapperFactory().getNativeWrapperFactory());
} }
public void shutdown() { public void shutdown() {
Assert.assert_it(isNativeEventThread());
nativeShutdown(getWrapperFactory().getNativeWrapperFactory()); nativeShutdown(getWrapperFactory().getNativeWrapperFactory());
} }
@ -152,16 +153,24 @@ public TreeModel getBookmarks() throws IllegalStateException
getWrapperFactory().verifyInitialized(); getWrapperFactory().verifyInitialized();
if (null == bookmarksTree) { if (null == bookmarksTree) {
int nativeBookmarks;
TreeNode root; TreeNode root;
if (-1 == Integer nativeBookmarks = (Integer)
(nativeBookmarks = NativeEventThread.instance.pushBlockingWCRunnable(new WCRunnable() {
nativeGetBookmarks(getWrapperFactory().getNativeWrapperFactory()))) { 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."); 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 we can't create a root, or we can't create a tree
if ((null == (root = new BookmarkEntryImpl(getWrapperFactory().getNativeWrapperFactory(), if ((null == (root = new BookmarkEntryImpl(getWrapperFactory().getNativeWrapperFactory(),
nativeBookmarks, null))) || nativeBookmarks.intValue(),
null))) ||
(null == (bookmarksTree = new DefaultTreeModel(root)))) { (null == (bookmarksTree = new DefaultTreeModel(root)))) {
throw new IllegalStateException("BookmarksImpl.getBookmarks(): Can't create RDFTreeModel."); throw new IllegalStateException("BookmarksImpl.getBookmarks(): Can't create RDFTreeModel.");
} }
@ -181,13 +190,23 @@ public void removeBookmark(BookmarkEntry bookmark)
public BookmarkEntry newBookmarkEntry(String url) public BookmarkEntry newBookmarkEntry(String url)
{ {
ParameterCheck.nonNull(url);
BookmarkEntry result = null; BookmarkEntry result = null;
final String finalUrl = new String(url);
getBookmarks(); getBookmarks();
int newNode; Integer newNode = (Integer)
NativeEventThread.instance.pushBlockingWCRunnable(new WCRunnable() {
public Object run() {
Integer result =
new Integer(nativeNewRDFNode(getNativeBrowserControl(),
finalUrl, false));
return result;
}
});
if (-1 != (newNode = nativeNewRDFNode(getNativeBrowserControl(), url, false))) { if (-1 != newNode.intValue()) {
result = new BookmarkEntryImpl(getNativeBrowserControl(), result = new BookmarkEntryImpl(getNativeBrowserControl(),
newNode, null); newNode.intValue(), null);
// use put instead of setProperty for jdk1.1.x compatibility. // use put instead of setProperty for jdk1.1.x compatibility.
result.getProperties().put(BookmarkEntry.NAME, url); result.getProperties().put(BookmarkEntry.NAME, url);
result.getProperties().put(BookmarkEntry.URL, url); result.getProperties().put(BookmarkEntry.URL, url);

Просмотреть файл

@ -81,7 +81,7 @@ public EventRegistrationImpl(WrapperFactory yourFactory,
super(yourFactory, yourBrowserControl); super(yourFactory, yourBrowserControl);
// pull out the NativeEventThread from the WrapperFactory // pull out the NativeEventThread from the WrapperFactory
nativeEventThread = getNativeEventThread(); nativeEventThread = NativeEventThread.instance;
} }
public void delete() public void delete()
@ -265,7 +265,7 @@ public static void main(String [] args)
Log.setApplicationName("EventRegistrationImpl"); Log.setApplicationName("EventRegistrationImpl");
Log.setApplicationVersion("0.0"); 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 { try {
org.mozilla.webclient.BrowserControlFactory.setAppData(args[0]); org.mozilla.webclient.BrowserControlFactory.setAppData(args[0]);

Просмотреть файл

@ -99,9 +99,9 @@ protected int getNativeBrowserControl() {
return nativeWebShell; return nativeWebShell;
} }
protected NativeEventThread getNativeEventThread() { protected boolean isNativeEventThread() {
return (NativeEventThread) return (Thread.currentThread() == NativeEventThread.instance);
getWrapperFactory().getNativeEventThread();
} }
} // end of class ImplObject } // end of class ImplObject

Просмотреть файл

@ -47,7 +47,7 @@ import org.mozilla.webclient.impl.WrapperFactory;
/** /**
* <p>This is a singleton class. All native events pass thru this class * <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> * methods.</p>
*/ */
@ -57,16 +57,15 @@ public class NativeEventThread extends Thread {
// Class variables // Class variables
// //
static NativeEventThread instance = null;
// //
// Attribute ivars // Attribute ivars
// //
/** private Object blockingResult;
* store the exception property, set when running a Runnable causes
* an exception.
*/
private Exception exception; private Exception blockingException;
// //
// Relationship ivars // Relationship ivars
@ -77,7 +76,7 @@ public class NativeEventThread extends Thread {
private BrowserControlCanvas browserControlCanvas; private BrowserControlCanvas browserControlCanvas;
private Stack runnablesWithNotify; private Stack blockingRunnables;
private Stack runnables; private Stack runnables;
@ -93,12 +92,14 @@ public class NativeEventThread extends Thread {
WrapperFactory yourFactory, WrapperFactory yourFactory,
int yourNativeWrapperFactory) { int yourNativeWrapperFactory) {
super(threadName); super(threadName);
Assert.assert_it(null == instance);
instance = this;
ParameterCheck.nonNull(yourFactory); ParameterCheck.nonNull(yourFactory);
wrapperFactory = yourFactory; wrapperFactory = yourFactory;
nativeWrapperFactory = yourNativeWrapperFactory; nativeWrapperFactory = yourNativeWrapperFactory;
runnablesWithNotify = new Stack(); blockingRunnables = new Stack();
runnables = new Stack(); runnables = new Stack();
} }
@ -127,33 +128,18 @@ public class NativeEventThread extends Thread {
wrapperFactory = null; 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 // Methods from Thread
// //
/** /**
* This method is the heart of webclient. It is called from * This method is the heart of webclient. It is called indirectly from
* {@link WrapperFactoryImpl#getNativeEventThread}. It calls * {@link WrapperFactoryImpl#initialize}. It calls nativeStartup, which
* nativeStartup, which does the per-window initialization, including * does the per-window initialization, including creating the native
* creating the native event queue which corresponds to this instance, * event queue which corresponds to this instance, then enters into an
* then enters into an infinite loop where processes native events, then * infinite loop where processes native events, then checks to see if
* checks to see if there are any listeners to add, and adds them if * there are any listeners to add, and adds them if necessary.
* necessary.
* @see nativeProcessEvents * @see nativeProcessEvents
@ -164,7 +150,16 @@ public class NativeEventThread extends Thread {
public void run() public void run()
{ {
// our owner must have put an event in the queue // 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. // Execute the event-loop.
@ -193,16 +188,32 @@ public void run()
if (!runnables.empty()) { if (!runnables.empty()) {
((Runnable)runnables.pop()).run(); ((Runnable)runnables.pop()).run();
} }
if (!runnablesWithNotify.empty()) { if (!blockingRunnables.empty()) {
((Runnable)runnablesWithNotify.pop()).run();
synchronized(wrapperFactory) {
try { try {
wrapperFactory.notify(); blockingException = null;
blockingResult =
((WCRunnable)blockingRunnables.pop()).run();
}
catch (RuntimeException e) {
blockingException = e;
}
// notify the pushBlockingWCRunnable() method.
try {
notify();
} }
catch (Exception e) { catch (Exception e) {
System.out.println("NativeEventThread.run: Exception: trying to send notify() to wrapperFactory: " + e + " " + e.getMessage()); 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); nativeProcessEvents(nativeWrapperFactory);
} }
@ -223,10 +234,32 @@ public void run()
} }
} }
void pushNotifyRunnable(Runnable toInvoke) { Object pushBlockingWCRunnable(WCRunnable toInvoke) {
Object result = null;
RuntimeException e = null;
synchronized (this) { 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;
} }
/** /**

Просмотреть файл

@ -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 * The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file * License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of * except in compliance with the License. You may obtain a copy of
@ -86,12 +85,11 @@ public void loadURL(String absoluteURL)
final String url = new String(absoluteURL); final String url = new String(absoluteURL);
Assert.assert_it(-1 != bc); Assert.assert_it(-1 != bc);
Runnable loadURL = new Runnable() { NativeEventThread.instance.pushRunnable(new Runnable() {
public void run() { public void run() {
NavigationImpl.this.nativeLoadURL(bc, url); NavigationImpl.this.nativeLoadURL(bc, url);
} }
}; });
getNativeEventThread().pushRunnable(loadURL);
} }
public void loadFromStream(InputStream stream, String uri, public void loadFromStream(InputStream stream, String uri,
@ -228,7 +226,7 @@ public static void main(String [] args)
Log.setApplicationName("NavigationImpl"); Log.setApplicationName("NavigationImpl");
Log.setApplicationVersion("0.0"); 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 { try {
org.mozilla.webclient.BrowserControlFactory.setAppData(args[0]); org.mozilla.webclient.BrowserControlFactory.setAppData(args[0]);

Просмотреть файл

@ -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 * The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file * License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of * except in compliance with the License. You may obtain a copy of
@ -106,31 +105,55 @@ public void setPref(String prefName, String prefValue)
if (null == prefName) { if (null == prefName) {
return; return;
} }
final String finalName = new String(prefName);
// determine the type of pref value: String, boolean, integer // determine the type of pref value: String, boolean, integer
try { try {
Integer intVal = Integer.valueOf(prefValue); final Integer intVal = Integer.valueOf(prefValue);
nativeSetIntPref(getWrapperFactory().getNativeWrapperFactory(), prefName, intVal.intValue()); NativeEventThread.instance.pushBlockingWCRunnable(new WCRunnable() {
public Object run() {
nativeSetIntPref(getWrapperFactory().getNativeWrapperFactory(), finalName, intVal.intValue());
return null;
}
});
} }
catch (NumberFormatException e) { catch (NumberFormatException e) {
// it's not an integer // it's not an integer
if (null != prefValue && if (null != prefValue &&
(prefValue.equals("true") || prefValue.equals("false"))) { (prefValue.equals("true") || prefValue.equals("false"))) {
Boolean boolVal = Boolean.valueOf(prefValue); final Boolean boolVal = Boolean.valueOf(prefValue);
nativeSetBoolPref(getWrapperFactory().getNativeWrapperFactory(), prefName, NativeEventThread.instance.pushBlockingWCRunnable(new WCRunnable(){
boolVal.booleanValue()); public Object run() {
nativeSetBoolPref(getWrapperFactory().getNativeWrapperFactory(),
finalName, boolVal.booleanValue());
return null;
}
});
} }
else { else {
// it must be a string // it must be a string
nativeSetUnicharPref(getWrapperFactory().getNativeWrapperFactory(), prefName, prefValue); final String finalValue = (null != prefValue) ?
new String(prefValue) : null;
NativeEventThread.instance.pushBlockingWCRunnable(new WCRunnable(){
public Object run() {
nativeSetUnicharPref(getWrapperFactory().getNativeWrapperFactory(), finalName, finalValue);
return null;
}
});
} }
} }
} }
public Properties getPrefs() public Properties getPrefs()
{ {
props = nativeGetPrefs(getWrapperFactory().getNativeWrapperFactory(), props); props = (Properties)
//Properties result = new Properties(); NativeEventThread.instance.pushBlockingWCRunnable(new WCRunnable() {
// result.put("webclientpref", "webclient_value"); public Object run() {
Properties result =
nativeGetPrefs(getWrapperFactory().getNativeWrapperFactory(),
PreferencesImpl.this.props);
return result;
}
});
return props; return props;
} }

Просмотреть файл

@ -1,4 +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 * The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file * License Version 1.1 (the "License"); you may not use this file
@ -46,45 +46,76 @@ public ProfileManagerImpl(WrapperFactory yourFactory)
} }
public void startup() { public void startup() {
Assert.assert_it(isNativeEventThread());
nativeStartup(getWrapperFactory().getNativeWrapperFactory(), null, null); nativeStartup(getWrapperFactory().getNativeWrapperFactory(), null, null);
} }
public void shutdown() { public void shutdown() {
Assert.assert_it(isNativeEventThread());
nativeShutdown(getWrapperFactory().getNativeWrapperFactory()); nativeShutdown(getWrapperFactory().getNativeWrapperFactory());
} }
public int getProfileCount() public int getProfileCount()
{ {
return nativeGetProfileCount(getWrapperFactory().getNativeWrapperFactory()); Integer result = (Integer)
NativeEventThread.instance.pushBlockingWCRunnable(new WCRunnable() {
public Object run() {
Integer count = new Integer(nativeGetProfileCount(getWrapperFactory().getNativeWrapperFactory()));
return count;
}
});
return result.intValue();
} }
public String [] getProfileList() public String [] getProfileList()
{ {
String [] list = null; String [] list =
list = nativeGetProfileList(getWrapperFactory().getNativeWrapperFactory()); (String []) NativeEventThread.instance.pushBlockingWCRunnable(new WCRunnable() {
public Object run() {
Object result = nativeGetProfileList(getWrapperFactory().getNativeWrapperFactory());
return result;
}
});
return list; return list;
} }
public boolean profileExists(String profileName) public boolean profileExists(String profileName)
{ {
boolean exists = false; ParameterCheck.nonNull(profileName);
exists = nativeProfileExists(getWrapperFactory().getNativeWrapperFactory(), final String finalStr = new String(profileName);
profileName); Boolean exists = (Boolean) NativeEventThread.instance.pushBlockingWCRunnable(new WCRunnable() {
return exists; public Object run() {
Boolean result = new Boolean(nativeProfileExists(getWrapperFactory().getNativeWrapperFactory(),
finalStr));
return result;
}
});
return exists.booleanValue();
} }
public String getCurrentProfile() public String getCurrentProfile()
{ {
String currProfile = null; String currProfile = (String)
currProfile = NativeEventThread.instance.pushBlockingWCRunnable(new WCRunnable() {
nativeGetCurrentProfile(getWrapperFactory().getNativeWrapperFactory()); public Object run() {
Object result = nativeGetCurrentProfile(getWrapperFactory().getNativeWrapperFactory());
return result;
}
});
return currProfile; return currProfile;
} }
public void setCurrentProfile(String profileName) public void setCurrentProfile(String profileName)
{ {
ParameterCheck.nonNull(profileName);
final String finalStr = new String(profileName);
NativeEventThread.instance.pushBlockingWCRunnable(new WCRunnable() {
public Object run() {
nativeSetCurrentProfile(getWrapperFactory().getNativeWrapperFactory(), nativeSetCurrentProfile(getWrapperFactory().getNativeWrapperFactory(),
profileName); finalStr);
return null;
}
});
} }
public void createNewProfile(String profileName, public void createNewProfile(String profileName,
@ -92,21 +123,50 @@ public void createNewProfile(String profileName,
String langcode, String langcode,
boolean useExistingDir) boolean useExistingDir)
{ {
ParameterCheck.nonNull(profileName);
final String finalProfileName = new String(profileName);
final String finalProfileDir = (null != nativeProfileDir) ?
new String(nativeProfileDir) : null;
final String finalLangcode = (null != langcode) ?
new String(langcode) : null;
final boolean finalExistingDir = useExistingDir;
NativeEventThread.instance.pushBlockingWCRunnable(new WCRunnable() {
public Object run() {
nativeCreateNewProfile(getWrapperFactory().getNativeWrapperFactory(), nativeCreateNewProfile(getWrapperFactory().getNativeWrapperFactory(),
profileName, nativeProfileDir, langcode, finalProfileName, finalProfileDir,
useExistingDir); finalLangcode, finalExistingDir);
return null;
}
});
} }
public void renameProfile(String currName, String newName) public void renameProfile(String currName, String newName)
{ {
ParameterCheck.nonNull(currName);
ParameterCheck.nonNull(newName);
final String finalCurrName = new String(currName);
final String finalNewName = new String(newName);
NativeEventThread.instance.pushBlockingWCRunnable(new WCRunnable() {
public Object run() {
nativeRenameProfile(getWrapperFactory().getNativeWrapperFactory(), nativeRenameProfile(getWrapperFactory().getNativeWrapperFactory(),
currName, newName); finalCurrName, finalNewName);
return null;
}
});
} }
public void deleteProfile(String profileName, boolean canDeleteFiles) public void deleteProfile(String profileName, boolean canDeleteFiles)
{ {
ParameterCheck.nonNull(profileName);
final String finalProfileName = new String(profileName);
final boolean finalCanDeleteFiles = canDeleteFiles;
NativeEventThread.instance.pushBlockingWCRunnable(new WCRunnable() {
public Object run() {
nativeDeleteProfile(getWrapperFactory().getNativeWrapperFactory(), nativeDeleteProfile(getWrapperFactory().getNativeWrapperFactory(),
profileName, canDeleteFiles); finalProfileName, finalCanDeleteFiles);
return null;
}
});
} }
public void cloneProfile(String currName) public void cloneProfile(String currName)

Просмотреть файл

@ -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 * The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file * License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of * except in compliance with the License. You may obtain a copy of
@ -103,7 +102,12 @@ public RDFEnumeration(int yourNativeContext,
protected void finalize() throws Throwable protected void finalize() throws Throwable
{ {
nativeFinalize(nativeContext); NativeEventThread.instance.pushBlockingWCRunnable(new WCRunnable() {
public Object run() {
nativeFinalize(RDFEnumeration.this.nativeContext);
return null;
}
});
super.finalize(); super.finalize();
} }
@ -114,19 +118,35 @@ protected void finalize() throws Throwable
public boolean hasMoreElements() public boolean hasMoreElements()
{ {
Assert.assert_it(-1 != nativeRDFNode); Assert.assert_it(-1 != nativeRDFNode);
return nativeHasMoreElements(nativeContext, nativeRDFNode); Boolean result = (Boolean)
NativeEventThread.instance.pushBlockingWCRunnable(new WCRunnable() {
public Object run() {
Boolean result =
new Boolean(nativeHasMoreElements(RDFEnumeration.this.nativeContext,
RDFEnumeration.this.nativeRDFNode));
return result;
}
});
return result.booleanValue();
} }
public Object nextElement() public Object nextElement()
{ {
Assert.assert_it(null != parent); Assert.assert_it(null != parent);
Object result = null; Object result = null;
int nextNativeRDFNode; Integer nextNativeRDFNode = (Integer)
NativeEventThread.instance.pushBlockingWCRunnable(new WCRunnable() {
public Object run() {
Integer result =
new Integer(nativeNextElement(RDFEnumeration.this.nativeContext,
RDFEnumeration.this.nativeRDFNode));
return result;
}
});
if (-1 != (nextNativeRDFNode = nativeNextElement(nativeContext, if (-1 != nextNativeRDFNode.intValue()) {
nativeRDFNode))) {
result = parent.newRDFTreeNode(nativeContext, result = parent.newRDFTreeNode(nativeContext,
nextNativeRDFNode, parent); nextNativeRDFNode.intValue(), parent);
} }
return result; return result;

Просмотреть файл

@ -0,0 +1,37 @@
/*
* 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
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is RaptorCanvas.
*
* The Initial Developer of the Original Code is Kirk Baker and
* Ian Wilkinson. Portions created by Kirk Baker and Ian Wilkinson are
* Copyright (C) 1999 Kirk Baker and Ian Wilkinson. All
* Rights Reserved.
*
* Contributor(s): Ed Burns <edburns@acm.org>
* Ashutosh Kulkarni <ashuk@eng.sun.com>
* Jason Mawdsley <jason@macadamian.com>
* Louis-Philippe Gagnon <louisphilippe@macadamian.com>
*/
package org.mozilla.webclient.impl.wrapper_native;
/**
* <p>Extend the concept of <code>java.lang.Runnable</code> to allow for
* the thing to have a return Object.</p>
*
*/
public interface WCRunnable {
public Object run();
}

Просмотреть файл

@ -138,26 +138,12 @@ public class WrapperFactoryImpl extends Object implements WrapperFactory {
BrowserControl result = new BrowserControlImpl(this); BrowserControl result = new BrowserControlImpl(this);
final int nativeBrowserControl = nativeCreateBrowserControl(); final int nativeBrowserControl = nativeCreateBrowserControl();
Runnable runnable = new Runnable() { eventThread.pushBlockingWCRunnable(new WCRunnable() {
public void run() { public Object run() {
WrapperFactoryImpl.this.nativeInitBrowserControl(nativeWrapperFactory, nativeBrowserControl); WrapperFactoryImpl.this.nativeInitBrowserControl(nativeWrapperFactory, nativeBrowserControl);
return null;
} }
}; });
eventThread.pushNotifyRunnable(runnable);
synchronized (this) {
try {
wait();
}
catch (Exception e) {
System.out.println("WrapperFactoryImpl.initialize(): interrupted while waiting\n\t for NativeEventThread to notify(): " + e +
" " + e.getMessage());
}
}
Exception e = eventThread.getAndClearException();
if (null != e) {
throw new IllegalStateException(e.getMessage());
}
browserControls.put(result, new Integer(nativeBrowserControl)); browserControls.put(result, new Integer(nativeBrowserControl));
return result; return result;
@ -169,27 +155,12 @@ public class WrapperFactoryImpl extends Object implements WrapperFactory {
if (null != (nativeBc = (Integer) browserControls.get(toDelete))) { if (null != (nativeBc = (Integer) browserControls.get(toDelete))) {
final int nativeBrowserControl = nativeBc.intValue(); final int nativeBrowserControl = nativeBc.intValue();
eventThread.pushBlockingWCRunnable(new WCRunnable() {
Runnable runnable = new Runnable() { public Object run() {
public void run() {
WrapperFactoryImpl.this.nativeDestroyBrowserControl(nativeBrowserControl); WrapperFactoryImpl.this.nativeDestroyBrowserControl(nativeBrowserControl);
return null;
} }
}; });
eventThread.pushNotifyRunnable(runnable);
synchronized (this) {
try {
wait();
}
catch (Exception e) {
System.out.println("WrapperFactoryImpl.deleteBrowserControl(): interrupted while waiting\n\t for NativeEventThread to notify(): " + e +
" " + e.getMessage());
}
}
Exception e = eventThread.getAndClearException();
if (null != e) {
throw new RuntimeException(e);
}
} }
} }
@ -288,15 +259,14 @@ public class WrapperFactoryImpl extends Object implements WrapperFactory {
nativeWrapperFactory); nativeWrapperFactory);
final String finalStr = new String(verifiedBinDirAbsolutePath); final String finalStr = new String(verifiedBinDirAbsolutePath);
Runnable runnable = new Runnable() {
eventThread.pushRunnable(new Runnable() {
public void run() { public void run() {
WrapperFactoryImpl.this.nativeAppInitialize(finalStr, WrapperFactoryImpl.this.nativeAppInitialize(finalStr,
nativeWrapperFactory, nativeWrapperFactory,
eventThread); eventThread);
} }
}; });
eventThread.pushNotifyRunnable(runnable);
eventThread.start(); eventThread.start();
synchronized (this) { synchronized (this) {
@ -306,12 +276,9 @@ public class WrapperFactoryImpl extends Object implements WrapperFactory {
catch (Exception e) { catch (Exception e) {
System.out.println("WrapperFactoryImpl.initialize(): interrupted while waiting\n\t for NativeEventThread to notify(): " + e + System.out.println("WrapperFactoryImpl.initialize(): interrupted while waiting\n\t for NativeEventThread to notify(): " + e +
" " + e.getMessage()); " " + e.getMessage());
}
}
Exception e = eventThread.getAndClearException();
if (null != e) {
throw new UnsatisfiedLinkError(e.getMessage()); throw new UnsatisfiedLinkError(e.getMessage());
} }
}
// //
// create app singletons // create app singletons
@ -323,35 +290,25 @@ public class WrapperFactoryImpl extends Object implements WrapperFactory {
bookmarks = new BookmarksImpl(this); bookmarks = new BookmarksImpl(this);
Assert.assert_it(null != bookmarks); Assert.assert_it(null != bookmarks);
runnable = new Runnable() { initialized = true;
public void run() { try {
eventThread.pushBlockingWCRunnable(new WCRunnable() {
public Object run() {
((Service)WrapperFactoryImpl.this.profileManager).startup(); ((Service)WrapperFactoryImpl.this.profileManager).startup();
((Service)WrapperFactoryImpl.this.prefs).startup(); ((Service)WrapperFactoryImpl.this.prefs).startup();
((Service)WrapperFactoryImpl.this.bookmarks).startup(); ((Service)WrapperFactoryImpl.this.bookmarks).startup();
WrapperFactoryImpl.this.nativeAppSetup(nativeWrapperFactory); WrapperFactoryImpl.this.nativeAppSetup(nativeWrapperFactory);
return null;
} }
}; });
eventThread.pushNotifyRunnable(runnable);
synchronized (this) {
// This causes the above Runnable to be executed.
try {
wait();
} }
catch (Exception exp) { catch (RuntimeException e) {
System.out.println("WrapperFactoryImpl.initialize(): interrupted while waiting\n\t for NativeEventThread to notify(): " + exp + initialized = false;
" " + exp.getMessage()); System.out.println("WrapperFactoryImpl.initialize: Can't start up singleton services: " + e + " " + e.getMessage());
} }
} }
e = eventThread.getAndClearException();
if (null != e) {
throw new UnsatisfiedLinkError(e.getMessage());
}
initialized = true;
}
public void verifyInitialized() throws IllegalStateException public void verifyInitialized() throws IllegalStateException
{ {
@ -362,8 +319,8 @@ public class WrapperFactoryImpl extends Object implements WrapperFactory {
public void terminate() throws Exception public void terminate() throws Exception
{ {
eventThread.pushNotifyRunnable(new Runnable() { eventThread.pushBlockingWCRunnable(new WCRunnable() {
public void run() { public Object run() {
Assert.assert_it(null != bookmarks); Assert.assert_it(null != bookmarks);
((Service)bookmarks).shutdown(); ((Service)bookmarks).shutdown();
((ImplObject)bookmarks).delete(); ((ImplObject)bookmarks).delete();
@ -379,30 +336,12 @@ public void terminate() throws Exception
((ImplObject)profileManager).delete(); ((ImplObject)profileManager).delete();
profileManager = null; profileManager = null;
nativeTerminate(nativeWrapperFactory); nativeTerminate(nativeWrapperFactory);
return null;
} }
}); });
synchronized (this) {
try {
wait();
}
catch (Exception e) {
System.out.println("WrapperFactoryImpl.initialize(): interrupted while waiting\n\t for NativeEventThread to notify(): " + e +
" " + e.getMessage());
}
}
Exception e = eventThread.getAndClearException();
if (null != e) {
throw new IllegalStateException(e.getMessage());
}
eventThread.delete(); eventThread.delete();
eventThread = null; eventThread = null;
}
public Object getNativeEventThread() {
verifyInitialized();
return eventThread;
} }
public int getNativeWrapperFactory() { public int getNativeWrapperFactory() {

Просмотреть файл

@ -452,7 +452,6 @@ static int PR_CALLBACK prefChanged(const char *name, void *closure)
if (nsnull == name || nsnull == closure) { if (nsnull == name || nsnull == closure) {
return NS_ERROR_NULL_POINTER; return NS_ERROR_NULL_POINTER;
} }
nsresult rv;
int result; int result;
JNIEnv *env = (JNIEnv *) JNU_GetEnv(gVm, JNI_VERSION); JNIEnv *env = (JNIEnv *) JNU_GetEnv(gVm, JNI_VERSION);
peStruct *pes = (peStruct *) closure; peStruct *pes = (peStruct *) closure;