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

- Use JDK 1.5 ConcurrentLinkedQueue to enable moving the enqueue and
  dequeue operations out of the synchronized block.

- Use a the new "result" property on WCRunnable to convey the result
  from the run() back to the caller.

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

- Make this an abstract class and add a read/write property called
  "result".
This commit is contained in:
edburns%acm.org 2007-01-17 13:45:22 +00:00
Родитель c9a49faa11
Коммит a780b50889
2 изменённых файлов: 46 добавлений и 65 удалений

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

@ -56,10 +56,6 @@ public class NativeEventThread extends Thread {
// Attribute ivars // Attribute ivars
// //
private Object blockingResult;
private Exception blockingException;
// //
// Relationship ivars // Relationship ivars
// //
@ -172,6 +168,8 @@ public void run()
System.out.println("NativeEventThread.run(): Exception: " + e + System.out.println("NativeEventThread.run(): Exception: " + e +
" while sleeping: " + e.getMessage()); " while sleeping: " + e.getMessage());
} }
runnable = runnables.poll();
wcRunnable = blockingRunnables.poll();
synchronized (this) { synchronized (this) {
// if we are have been told to delete ourselves // if we are have been told to delete ourselves
if (null == this.wrapperFactory) { if (null == this.wrapperFactory) {
@ -184,8 +182,7 @@ public void run()
return; return;
} }
if (!runnables.isEmpty()) { if (null!= runnable) {
runnable = (Runnable)runnables.poll();
if (LOGGER.isLoggable(Level.FINEST)) { if (LOGGER.isLoggable(Level.FINEST)) {
LOGGER.finest("NativeEventThread.run: About to run " + LOGGER.finest("NativeEventThread.run: About to run " +
runnable.toString()); runnable.toString());
@ -196,46 +193,25 @@ public void run()
runnable.toString()); runnable.toString());
} }
} }
if (!blockingRunnables.isEmpty()) { if (null != wcRunnable) {
wcRunnable = (WCRunnable)blockingRunnables.poll(); if (LOGGER.isLoggable(Level.FINEST)) {
try { LOGGER.finest("NativeEventThread.run: About to run " +
blockingException = null; wcRunnable.toString());
if (LOGGER.isLoggable(Level.FINEST)) { }
LOGGER.finest("NativeEventThread.run: About to run " + wcRunnable.setResult(wcRunnable.run());
wcRunnable.toString()); if (LOGGER.isLoggable(Level.FINEST)) {
} LOGGER.finest("NativeEventThread.run: Return from run " +
blockingResult = wcRunnable.run(); wcRunnable.toString());
if (LOGGER.isLoggable(Level.FINEST)) { }
LOGGER.finest("NativeEventThread.run: Return from run " +
wcRunnable.toString());
}
}
catch (RuntimeException e) {
blockingException = e;
}
// notify the pushBlockingWCRunnable() method. // notify the pushBlockingWCRunnable() method.
try { synchronized (wcRunnable) {
notifyAll(); try {
} wcRunnable.notifyAll();
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 {
if (LOGGER.isLoggable(Level.FINEST)) {
LOGGER.finest("NativeEventThread.run: About to wait for caller to grab result from " +
wcRunnable.toString());
} }
wait(); catch (Exception e) {
if (LOGGER.isLoggable(Level.FINEST)) { System.out.println("NativeEventThread.run: Exception: trying to notify for blocking result:" + e + " " + e.getMessage());
LOGGER.finest("NativeEventThread.run: Return from wait for caller to grab result from " +
wcRunnable.toString());
} }
} }
catch (Exception e) {
System.out.println("NativeEventThread.run: Exception: trying to waiting for pushBlockingWCRunnable:" + e + " " + e.getMessage());
}
} }
nativeProcessEvents(nativeWrapperFactory); nativeProcessEvents(nativeWrapperFactory);
} }
@ -256,24 +232,27 @@ public void run()
} }
} }
Object pushBlockingWCRunnable(WCRunnable toInvoke) { Object pushBlockingWCRunnable(WCRunnable toInvoke) throws RuntimeException {
Object result = null; Object result = null;
RuntimeException e = null;
if (Thread.currentThread().getName().equals(instance.getName())){ if (Thread.currentThread().getName().equals(instance.getName())){
result = toInvoke.run(); toInvoke.run();
result = toInvoke.getResult();
if (result instanceof RuntimeException) {
throw ((RuntimeException) result);
}
return result; return result;
} }
synchronized (this) { blockingRunnables.add(toInvoke);
blockingRunnables.add(toInvoke); synchronized (toInvoke) {
try { try {
if (LOGGER.isLoggable(Level.FINEST)) { if (LOGGER.isLoggable(Level.FINEST)) {
LOGGER.finest("NativeEventThread.pushBlockingWCRunnable: " + LOGGER.finest("NativeEventThread.pushBlockingWCRunnable: " +
" About to wait for NativeEventThread to run " + " About to wait for NativeEventThread to run " +
toInvoke.toString()); toInvoke.toString());
} }
wait(); toInvoke.wait();
if (LOGGER.isLoggable(Level.FINEST)) { if (LOGGER.isLoggable(Level.FINEST)) {
LOGGER.finest("NativeEventThread.pushBlockingWCRunnable: " + LOGGER.finest("NativeEventThread.pushBlockingWCRunnable: " +
" Return from wait for NativeEventThread to run " + " Return from wait for NativeEventThread to run " +
@ -283,20 +262,12 @@ public void run()
catch (Exception se) { catch (Exception se) {
System.out.println("NativeEventThread.pushBlockingWCRunnable: Exception: while waiting for blocking result: " + se + " " + se.getMessage()); System.out.println("NativeEventThread.pushBlockingWCRunnable: Exception: while waiting for blocking result: " + se + " " + se.getMessage());
} }
result = blockingResult; }
if (null != blockingException) { result = toInvoke.getResult();
e = new RuntimeException(blockingException); if (result instanceof RuntimeException) {
} throw ((RuntimeException) result);
try { }
notifyAll();
}
catch (Exception se) {
System.out.println("NativeEventThread.pushBlockingWCRunnable: Exception: trying to send notifyAll() to NativeEventThread: " + se + " " + se.getMessage());
}
}
if (null != e) {
throw e;
}
return result; return result;
} }

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

@ -30,8 +30,18 @@ package org.mozilla.webclient.impl.wrapper_native;
* *
*/ */
public interface WCRunnable { public abstract class WCRunnable {
public Object run(); public abstract Object run();
private Object result = null;
public Object getResult() {
return result;
}
public void setResult(Object result) {
this.result = result;
}
} }