提交 0a32b7c7 编写于 作者: P pchelko

8025588: [macosx] Frozen AppKit thread in 7u40

Reviewed-by: anthony, art, serb
上级 5fc102a7
...@@ -620,8 +620,7 @@ public class CInputMethod extends InputMethodAdapter { ...@@ -620,8 +620,7 @@ public class CInputMethod extends InputMethodAdapter {
retString[0] = new String(selectedText); retString[0] = new String(selectedText);
}} }}
}, fAwtFocussedComponent); }, fAwtFocussedComponent);
} catch (InterruptedException ie) { ie.printStackTrace(); } } catch (InvocationTargetException ite) { ite.printStackTrace(); }
catch (InvocationTargetException ite) { ite.printStackTrace(); }
synchronized(retString) { return retString[0]; } synchronized(retString) { return retString[0]; }
} }
...@@ -669,8 +668,7 @@ public class CInputMethod extends InputMethodAdapter { ...@@ -669,8 +668,7 @@ public class CInputMethod extends InputMethodAdapter {
}} }}
}, fAwtFocussedComponent); }, fAwtFocussedComponent);
} catch (InterruptedException ie) { ie.printStackTrace(); } } catch (InvocationTargetException ite) { ite.printStackTrace(); }
catch (InvocationTargetException ite) { ite.printStackTrace(); }
synchronized(returnValue) { return returnValue; } synchronized(returnValue) { return returnValue; }
} }
...@@ -695,8 +693,7 @@ public class CInputMethod extends InputMethodAdapter { ...@@ -695,8 +693,7 @@ public class CInputMethod extends InputMethodAdapter {
returnValue[0] = fIMContext.getInsertPositionOffset(); returnValue[0] = fIMContext.getInsertPositionOffset();
}} }}
}, fAwtFocussedComponent); }, fAwtFocussedComponent);
} catch (InterruptedException ie) { ie.printStackTrace(); } } catch (InvocationTargetException ite) { ite.printStackTrace(); }
catch (InvocationTargetException ite) { ite.printStackTrace(); }
returnValue[1] = fCurrentTextLength; returnValue[1] = fCurrentTextLength;
synchronized(returnValue) { return returnValue; } synchronized(returnValue) { return returnValue; }
...@@ -743,8 +740,7 @@ public class CInputMethod extends InputMethodAdapter { ...@@ -743,8 +740,7 @@ public class CInputMethod extends InputMethodAdapter {
} }
}} }}
}, fAwtFocussedComponent); }, fAwtFocussedComponent);
} catch (InterruptedException ie) { ie.printStackTrace(); } } catch (InvocationTargetException ite) { ite.printStackTrace(); }
catch (InvocationTargetException ite) { ite.printStackTrace(); }
synchronized(rect) { return rect; } synchronized(rect) { return rect; }
} }
...@@ -764,8 +760,7 @@ public class CInputMethod extends InputMethodAdapter { ...@@ -764,8 +760,7 @@ public class CInputMethod extends InputMethodAdapter {
insertPositionOffset[0] = fIMContext.getInsertPositionOffset(); insertPositionOffset[0] = fIMContext.getInsertPositionOffset();
}} }}
}, fAwtFocussedComponent); }, fAwtFocussedComponent);
} catch (InterruptedException ie) { ie.printStackTrace(); } } catch (InvocationTargetException ite) { ite.printStackTrace(); }
catch (InvocationTargetException ite) { ite.printStackTrace(); }
// This bit of gymnastics ensures that the returned location is within the composed text. // This bit of gymnastics ensures that the returned location is within the composed text.
// If it falls outside that region, the input method will commit the text, which is inconsistent with native // If it falls outside that region, the input method will commit the text, which is inconsistent with native
......
...@@ -884,7 +884,7 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo ...@@ -884,7 +884,7 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
//Posting an empty to flush the EventQueue without blocking the main thread //Posting an empty to flush the EventQueue without blocking the main thread
} }
}, target); }, target);
} catch (InterruptedException | InvocationTargetException e) { } catch (InvocationTargetException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
......
...@@ -97,6 +97,6 @@ public class CViewEmbeddedFrame extends EmbeddedFrame { ...@@ -97,6 +97,6 @@ public class CViewEmbeddedFrame extends EmbeddedFrame {
setVisible(true); setVisible(true);
} }
}, this); }, this);
} catch (InterruptedException | InvocationTargetException ex) {} } catch (InvocationTargetException ex) {}
} }
} }
...@@ -548,22 +548,18 @@ public final class LWCToolkit extends LWToolkit { ...@@ -548,22 +548,18 @@ public final class LWCToolkit extends LWToolkit {
// Any selector invoked using ThreadUtilities performOnMainThread will be processed in doAWTRunLoop // Any selector invoked using ThreadUtilities performOnMainThread will be processed in doAWTRunLoop
// The InvocationEvent will call LWCToolkit.stopAWTRunLoop() when finished, which will stop our manual runloop // The InvocationEvent will call LWCToolkit.stopAWTRunLoop() when finished, which will stop our manual runloop
// Does not dispatch native events while in the loop // Does not dispatch native events while in the loop
public static void invokeAndWait(Runnable event, Component component) throws InterruptedException, InvocationTargetException { public static void invokeAndWait(Runnable runnable, Component component) throws InvocationTargetException {
final long mediator = createAWTRunLoopMediator(); final long mediator = createAWTRunLoopMediator();
InvocationEvent invocationEvent = InvocationEvent invocationEvent =
new InvocationEvent(component != null ? component : Toolkit.getDefaultToolkit(), event) { new InvocationEvent(component != null ? component : Toolkit.getDefaultToolkit(),
@Override runnable,
public void dispatch() { () -> {
try {
super.dispatch();
} finally {
if (mediator != 0) { if (mediator != 0) {
stopAWTRunLoop(mediator); stopAWTRunLoop(mediator);
} }
} },
} true);
};
if (component != null) { if (component != null) {
AppContext appContext = SunToolkit.targetToAppContext(component); AppContext appContext = SunToolkit.targetToAppContext(component);
......
...@@ -1159,6 +1159,10 @@ public class EventQueue { ...@@ -1159,6 +1159,10 @@ public class EventQueue {
if (entry.event instanceof SentEvent) { if (entry.event instanceof SentEvent) {
((SentEvent)entry.event).dispose(); ((SentEvent)entry.event).dispose();
} }
if (entry.event instanceof InvocationEvent) {
AWTAccessor.getInvocationEventAccessor()
.dispose((InvocationEvent)entry.event);
}
if (prev == null) { if (prev == null) {
queues[i].head = entry.next; queues[i].head = entry.next;
} else { } else {
......
...@@ -25,6 +25,8 @@ ...@@ -25,6 +25,8 @@
package java.awt.event; package java.awt.event;
import sun.awt.AWTAccessor;
import java.awt.ActiveEvent; import java.awt.ActiveEvent;
import java.awt.AWTEvent; import java.awt.AWTEvent;
...@@ -56,6 +58,15 @@ import java.awt.AWTEvent; ...@@ -56,6 +58,15 @@ import java.awt.AWTEvent;
*/ */
public class InvocationEvent extends AWTEvent implements ActiveEvent { public class InvocationEvent extends AWTEvent implements ActiveEvent {
static {
AWTAccessor.setInvocationEventAccessor(new AWTAccessor.InvocationEventAccessor() {
@Override
public void dispose(InvocationEvent invocationEvent) {
invocationEvent.finishedDispatching(false);
}
});
}
/** /**
* Marks the first integer id for the range of invocation event ids. * Marks the first integer id for the range of invocation event ids.
*/ */
...@@ -78,11 +89,21 @@ public class InvocationEvent extends AWTEvent implements ActiveEvent { ...@@ -78,11 +89,21 @@ public class InvocationEvent extends AWTEvent implements ActiveEvent {
/** /**
* The (potentially null) Object whose notifyAll() method will be called * The (potentially null) Object whose notifyAll() method will be called
* immediately after the Runnable.run() method has returned or thrown an exception. * immediately after the Runnable.run() method has returned or thrown an exception
* or after the event was disposed.
* *
* @see #isDispatched * @see #isDispatched
*/ */
protected Object notifier; protected volatile Object notifier;
/**
* The (potentially null) Runnable whose run() method will be called
* immediately after the event was dispatched or disposed.
*
* @see #isDispatched
* @since 1.8
*/
private final Runnable listener;
/** /**
* Indicates whether the <code>run()</code> method of the <code>runnable</code> * Indicates whether the <code>run()</code> method of the <code>runnable</code>
...@@ -147,7 +168,7 @@ public class InvocationEvent extends AWTEvent implements ActiveEvent { ...@@ -147,7 +168,7 @@ public class InvocationEvent extends AWTEvent implements ActiveEvent {
* @see #InvocationEvent(Object, Runnable, Object, boolean) * @see #InvocationEvent(Object, Runnable, Object, boolean)
*/ */
public InvocationEvent(Object source, Runnable runnable) { public InvocationEvent(Object source, Runnable runnable) {
this(source, runnable, null, false); this(source, INVOCATION_DEFAULT, runnable, null, null, false);
} }
/** /**
...@@ -171,7 +192,8 @@ public class InvocationEvent extends AWTEvent implements ActiveEvent { ...@@ -171,7 +192,8 @@ public class InvocationEvent extends AWTEvent implements ActiveEvent {
* @param notifier The {@code Object} whose <code>notifyAll</code> * @param notifier The {@code Object} whose <code>notifyAll</code>
* method will be called after * method will be called after
* <code>Runnable.run</code> has returned or * <code>Runnable.run</code> has returned or
* thrown an exception * thrown an exception or after the event was
* disposed
* @param catchThrowables Specifies whether <code>dispatch</code> * @param catchThrowables Specifies whether <code>dispatch</code>
* should catch Throwable when executing * should catch Throwable when executing
* the <code>Runnable</code>'s <code>run</code> * the <code>Runnable</code>'s <code>run</code>
...@@ -185,7 +207,39 @@ public class InvocationEvent extends AWTEvent implements ActiveEvent { ...@@ -185,7 +207,39 @@ public class InvocationEvent extends AWTEvent implements ActiveEvent {
*/ */
public InvocationEvent(Object source, Runnable runnable, Object notifier, public InvocationEvent(Object source, Runnable runnable, Object notifier,
boolean catchThrowables) { boolean catchThrowables) {
this(source, INVOCATION_DEFAULT, runnable, notifier, catchThrowables); this(source, INVOCATION_DEFAULT, runnable, notifier, null, catchThrowables);
}
/**
* Constructs an <code>InvocationEvent</code> with the specified
* source which will execute the runnable's <code>run</code>
* method when dispatched. If listener is non-<code>null</code>,
* <code>listener.run()</code> will be called immediately after
* <code>run</code> has returned, thrown an exception or the event
* was disposed.
* <p>This method throws an <code>IllegalArgumentException</code>
* if <code>source</code> is <code>null</code>.
*
* @param source The <code>Object</code> that originated
* the event
* @param runnable The <code>Runnable</code> whose
* <code>run</code> method will be
* executed
* @param listener The <code>Runnable</code>Runnable whose
* <code>run()</code> method will be called
* after the {@code InvocationEvent}
* was dispatched or disposed
* @param catchThrowables Specifies whether <code>dispatch</code>
* should catch Throwable when executing
* the <code>Runnable</code>'s <code>run</code>
* method, or should instead propagate those
* Throwables to the EventDispatchThread's
* dispatch loop
* @throws IllegalArgumentException if <code>source</code> is null
*/
public InvocationEvent(Object source, Runnable runnable, Runnable listener,
boolean catchThrowables) {
this(source, INVOCATION_DEFAULT, runnable, null, listener, catchThrowables);
} }
/** /**
...@@ -208,7 +262,8 @@ public class InvocationEvent extends AWTEvent implements ActiveEvent { ...@@ -208,7 +262,8 @@ public class InvocationEvent extends AWTEvent implements ActiveEvent {
* @param notifier The <code>Object</code> whose <code>notifyAll</code> * @param notifier The <code>Object</code> whose <code>notifyAll</code>
* method will be called after * method will be called after
* <code>Runnable.run</code> has returned or * <code>Runnable.run</code> has returned or
* thrown an exception * thrown an exception or after the event was
* disposed
* @param catchThrowables Specifies whether <code>dispatch</code> * @param catchThrowables Specifies whether <code>dispatch</code>
* should catch Throwable when executing the * should catch Throwable when executing the
* <code>Runnable</code>'s <code>run</code> * <code>Runnable</code>'s <code>run</code>
...@@ -221,13 +276,18 @@ public class InvocationEvent extends AWTEvent implements ActiveEvent { ...@@ -221,13 +276,18 @@ public class InvocationEvent extends AWTEvent implements ActiveEvent {
*/ */
protected InvocationEvent(Object source, int id, Runnable runnable, protected InvocationEvent(Object source, int id, Runnable runnable,
Object notifier, boolean catchThrowables) { Object notifier, boolean catchThrowables) {
this(source, id, runnable, notifier, null, catchThrowables);
}
private InvocationEvent(Object source, int id, Runnable runnable,
Object notifier, Runnable listener, boolean catchThrowables) {
super(source, id); super(source, id);
this.runnable = runnable; this.runnable = runnable;
this.notifier = notifier; this.notifier = notifier;
this.listener = listener;
this.catchExceptions = catchThrowables; this.catchExceptions = catchThrowables;
this.when = System.currentTimeMillis(); this.when = System.currentTimeMillis();
} }
/** /**
* Executes the Runnable's <code>run()</code> method and notifies the * Executes the Runnable's <code>run()</code> method and notifies the
* notifier (if any) when <code>run()</code> has returned or thrown an exception. * notifier (if any) when <code>run()</code> has returned or thrown an exception.
...@@ -251,13 +311,7 @@ public class InvocationEvent extends AWTEvent implements ActiveEvent { ...@@ -251,13 +311,7 @@ public class InvocationEvent extends AWTEvent implements ActiveEvent {
runnable.run(); runnable.run();
} }
} finally { } finally {
dispatched = true; finishedDispatching(true);
if (notifier != null) {
synchronized (notifier) {
notifier.notifyAll();
}
}
} }
} }
...@@ -330,6 +384,25 @@ public class InvocationEvent extends AWTEvent implements ActiveEvent { ...@@ -330,6 +384,25 @@ public class InvocationEvent extends AWTEvent implements ActiveEvent {
return dispatched; return dispatched;
} }
/**
* Called when the event was dispatched or disposed
* @param dispatched true if the event was dispatched
* false if the event was disposed
*/
private void finishedDispatching(boolean dispatched) {
this.dispatched = dispatched;
if (notifier != null) {
synchronized (notifier) {
notifier.notifyAll();
}
}
if (listener != null) {
listener.run();
}
}
/** /**
* Returns a parameter string identifying this event. * Returns a parameter string identifying this event.
* This method is useful for event-logging and for debugging. * This method is useful for event-logging and for debugging.
......
...@@ -31,6 +31,7 @@ import java.awt.*; ...@@ -31,6 +31,7 @@ import java.awt.*;
import java.awt.KeyboardFocusManager; import java.awt.KeyboardFocusManager;
import java.awt.DefaultKeyboardFocusManager; import java.awt.DefaultKeyboardFocusManager;
import java.awt.event.InputEvent; import java.awt.event.InputEvent;
import java.awt.event.InvocationEvent;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import java.awt.geom.Point2D; import java.awt.geom.Point2D;
import java.awt.peer.ComponentPeer; import java.awt.peer.ComponentPeer;
...@@ -720,6 +721,13 @@ public final class AWTAccessor { ...@@ -720,6 +721,13 @@ public final class AWTAccessor {
void setPlatformResources(ResourceBundle bundle); void setPlatformResources(ResourceBundle bundle);
} }
/*
* An accessor object for the InvocationEvent class
*/
public interface InvocationEventAccessor {
void dispose(InvocationEvent event);
}
/* /*
* Accessor instances are initialized in the static initializers of * Accessor instances are initialized in the static initializers of
* corresponding AWT classes by using setters defined below. * corresponding AWT classes by using setters defined below.
...@@ -748,6 +756,7 @@ public final class AWTAccessor { ...@@ -748,6 +756,7 @@ public final class AWTAccessor {
private static DefaultKeyboardFocusManagerAccessor defaultKeyboardFocusManagerAccessor; private static DefaultKeyboardFocusManagerAccessor defaultKeyboardFocusManagerAccessor;
private static SequencedEventAccessor sequencedEventAccessor; private static SequencedEventAccessor sequencedEventAccessor;
private static ToolkitAccessor toolkitAccessor; private static ToolkitAccessor toolkitAccessor;
private static InvocationEventAccessor invocationEventAccessor;
/* /*
* Set an accessor object for the java.awt.Component class. * Set an accessor object for the java.awt.Component class.
...@@ -1159,4 +1168,18 @@ public final class AWTAccessor { ...@@ -1159,4 +1168,18 @@ public final class AWTAccessor {
return toolkitAccessor; return toolkitAccessor;
} }
/*
* Get the accessor object for the java.awt.event.InvocationEvent class.
*/
public static void setInvocationEventAccessor(InvocationEventAccessor invocationEventAccessor) {
AWTAccessor.invocationEventAccessor = invocationEventAccessor;
}
/*
* Set the accessor object for the java.awt.event.InvocationEvent class.
*/
public static InvocationEventAccessor getInvocationEventAccessor() {
return invocationEventAccessor;
}
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册