diff --git a/mozilla/java/webclient/classes_spec/org/mozilla/webclient/impl/WrapperFactory.java b/mozilla/java/webclient/classes_spec/org/mozilla/webclient/impl/WrapperFactory.java index eaeab7b836d..45544f7f7fa 100644 --- a/mozilla/java/webclient/classes_spec/org/mozilla/webclient/impl/WrapperFactory.java +++ b/mozilla/java/webclient/classes_spec/org/mozilla/webclient/impl/WrapperFactory.java @@ -26,6 +26,7 @@ package org.mozilla.webclient.impl; +import java.util.concurrent.CountDownLatch; import org.mozilla.webclient.BrowserControl; /** @@ -94,4 +95,11 @@ public interface WrapperFactory { */ public int getNativeBrowserControl(BrowserControl bc); + + /** + *
Used during startup to allow the NativeEventThread to tell the + * WrapperFactory that it is ready + * to receive events into its queue.
+ */ + public CountDownLatch getOneCountLatch(); } diff --git a/mozilla/java/webclient/classes_spec/org/mozilla/webclient/impl/wrapper_native/CocoaAppKitThreadDelegatingNativeEventThread.java b/mozilla/java/webclient/classes_spec/org/mozilla/webclient/impl/wrapper_native/CocoaAppKitThreadDelegatingNativeEventThread.java index 6c0b50ab1f4..112a918e9f4 100644 --- a/mozilla/java/webclient/classes_spec/org/mozilla/webclient/impl/wrapper_native/CocoaAppKitThreadDelegatingNativeEventThread.java +++ b/mozilla/java/webclient/classes_spec/org/mozilla/webclient/impl/wrapper_native/CocoaAppKitThreadDelegatingNativeEventThread.java @@ -121,7 +121,17 @@ public class CocoaAppKitThreadDelegatingNativeEventThread extends NativeEventThr toInvoke.toString() + "."); } - Object result = toInvoke.run(); + Object result = null; + try { + result = toInvoke.run(); + } + catch (RuntimeException e) { + if (LOGGER.isLoggable(Level.SEVERE)) { + LOGGER.log(Level.SEVERE, "Exception while invoking " + + toInvoke.toString() + " on AppKit Thread", e); + } + throw e; + } if (LOGGER.isLoggable(Level.FINEST)) { LOGGER.finest("On AppKitThread, returned from calling " + @@ -140,7 +150,16 @@ public class CocoaAppKitThreadDelegatingNativeEventThread extends NativeEventThr toInvoke.toString() + "."); } - toInvoke.run(); + try { + toInvoke.run(); + } + catch (RuntimeException e) { + if (LOGGER.isLoggable(Level.SEVERE)) { + LOGGER.log(Level.SEVERE, "Exception while invoking " + + toInvoke.toString() + " on AppKit Thread", e); + } + throw e; + } if (LOGGER.isLoggable(Level.FINEST)) { LOGGER.finest("On AppKitThread, non-blocking, returned from calling " + diff --git a/mozilla/java/webclient/classes_spec/org/mozilla/webclient/impl/wrapper_native/NativeEventThread.java b/mozilla/java/webclient/classes_spec/org/mozilla/webclient/impl/wrapper_native/NativeEventThread.java index d623ea07654..51a81f45342 100644 --- a/mozilla/java/webclient/classes_spec/org/mozilla/webclient/impl/wrapper_native/NativeEventThread.java +++ b/mozilla/java/webclient/classes_spec/org/mozilla/webclient/impl/wrapper_native/NativeEventThread.java @@ -160,17 +160,9 @@ public void run() // our owner must have put an event in the queue Assert.assert_it(!runnables.isEmpty()); ((Runnable)runnables.poll()).run(); - synchronized (wrapperFactory) { - try { - wrapperFactory.notifyAll(); - } - catch (Exception e) { - if (LOGGER.isLoggable(Level.SEVERE)) { - LOGGER.log(Level.SEVERE, - "Exception trying to send notifyAll() to WrapperFactoryImpl on startup", e); - } - } - } + + // Tell the wrapper factory we're ready to receive events + wrapperFactory.getOneCountLatch().countDown(); // // Execute the event-loop. diff --git a/mozilla/java/webclient/classes_spec/org/mozilla/webclient/impl/wrapper_native/WrapperFactoryImpl.java b/mozilla/java/webclient/classes_spec/org/mozilla/webclient/impl/wrapper_native/WrapperFactoryImpl.java index 0ced33989d8..9d71dbb4d1f 100644 --- a/mozilla/java/webclient/classes_spec/org/mozilla/webclient/impl/wrapper_native/WrapperFactoryImpl.java +++ b/mozilla/java/webclient/classes_spec/org/mozilla/webclient/impl/wrapper_native/WrapperFactoryImpl.java @@ -28,7 +28,6 @@ import java.util.logging.Logger; import org.mozilla.util.Assert; import org.mozilla.util.Log; import org.mozilla.util.Utilities; -import org.mozilla.util.ParameterCheck; import org.mozilla.util.ReturnRunnable; import org.mozilla.webclient.BrowserControl; @@ -46,6 +45,7 @@ import org.mozilla.dom.DOMAccessor; import java.util.Map; import java.util.HashMap; +import java.util.concurrent.CountDownLatch; /** *This class is the hub of the startup and shutdown sequence for @@ -105,6 +105,7 @@ public class WrapperFactoryImpl extends Object implements WrapperFactory { protected String profileName = "webclient"; protected boolean initialized = false; protected boolean terminated = false; + protected CountDownLatch oneCountLatch = null; // Relationship Instance Variables @@ -142,6 +143,7 @@ public class WrapperFactoryImpl extends Object implements WrapperFactory { { super(); browserControls = new HashMap(); + oneCountLatch = new CountDownLatch(1); } @@ -152,6 +154,10 @@ public class WrapperFactoryImpl extends Object implements WrapperFactory { // // Methods from webclient.WrapperFactory // + + public CountDownLatch getOneCountLatch() { + return oneCountLatch; + } public BrowserControl newBrowserControl() throws InstantiationException, IllegalAccessException, IllegalStateException { verifyInitialized(); @@ -366,17 +372,19 @@ public class WrapperFactoryImpl extends Object implements WrapperFactory { }); eventThread.start(); - synchronized (this) { - try { - wait(); - } - catch (Exception e) { - System.out.println("WrapperFactoryImpl.initialize(): interrupted while waiting\n\t for NativeEventThread to notify(): " + e + - " " + e.getMessage()); - throw new UnsatisfiedLinkError(e.getMessage()); - } - } - + + try { + getOneCountLatch().await(); + } + catch (Exception e) { + if (LOGGER.isLoggable(Level.SEVERE)) { + LOGGER.log(Level.SEVERE, + "WrapperFactoryImpl.initialize(): interrupted while waiting\n\t for NativeEventThread to countDown(): ", e); + } + throw new UnsatisfiedLinkError(e.getMessage()); + } + + // // create app singletons // diff --git a/mozilla/java/webclient/src_moz/cocoa/CocoaBrowserControlCanvas.mm b/mozilla/java/webclient/src_moz/cocoa/CocoaBrowserControlCanvas.mm index 73b9948d74a..180c2daa309 100644 --- a/mozilla/java/webclient/src_moz/cocoa/CocoaBrowserControlCanvas.mm +++ b/mozilla/java/webclient/src_moz/cocoa/CocoaBrowserControlCanvas.mm @@ -74,9 +74,10 @@ jclass clazz = env->GetObjectClass(javaThis); jmethodID mid = env->GetMethodID(clazz, "doRunReturnRunnableOnAppKitThread", "(Lorg/mozilla/util/ReturnRunnable;)Ljava/lang/Object;"); + env->ExceptionClear(); result = env->CallObjectMethod(javaThis, mid, toInvoke); if (env->ExceptionOccurred()) { - ::util_ThrowExceptionToJava(env, "Cannot call back into Java"); + ::util_ThrowExceptionToJava(env, "Cannot call back into Java from Objective-C doRunReturnRunnableOnAppKitThread"); } nsValue = [NSValue value:&result withObjCType:@encode(jobject)]; [args addObject: nsValue]; @@ -99,9 +100,10 @@ jclass clazz = env->GetObjectClass(javaThis); jmethodID mid = env->GetMethodID(clazz, "doRunRunnableOnAppKitThread", "(Ljava/lang/Runnable;)V"); + env->ExceptionClear(); env->CallVoidMethod(javaThis, mid, toInvoke); if (env->ExceptionOccurred()) { - ::util_ThrowExceptionToJava(env, "Cannot call back into Java"); + ::util_ThrowExceptionToJava(env, "Cannot call back into Java from Objective-C doRunRunnableOnAppKitThread"); } return; } diff --git a/mozilla/java/webclient/src_share/jni_util.cpp b/mozilla/java/webclient/src_share/jni_util.cpp index b053efd7d76..76bb1fe4f1a 100644 --- a/mozilla/java/webclient/src_share/jni_util.cpp +++ b/mozilla/java/webclient/src_share/jni_util.cpp @@ -404,6 +404,7 @@ void util_ThrowExceptionToJava (JNIEnv * env, const char * exceptionClass, const char * message) { if (env->ExceptionOccurred()) { + env->ExceptionDescribe(); env->ExceptionClear(); } jclass excCls = env->FindClass(exceptionClass);