Mercurial > hg > openjdk > lambda > jdk
changeset 10455:857d6f78f241
8025588: [macosx] Frozen AppKit thread in 7u40
Reviewed-by: anthony, art, serb
author | pchelko |
---|---|
date | Thu, 10 Oct 2013 11:40:06 +0400 |
parents | 81ea6299230a |
children | 31a156bae7cb |
files | src/macosx/classes/sun/lwawt/macosx/CInputMethod.java src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java src/macosx/classes/sun/lwawt/macosx/CViewEmbeddedFrame.java src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java src/share/classes/java/awt/EventQueue.java src/share/classes/java/awt/event/InvocationEvent.java src/share/classes/sun/awt/AWTAccessor.java |
diffstat | 7 files changed, 127 insertions(+), 36 deletions(-) [+] |
line wrap: on
line diff
--- a/src/macosx/classes/sun/lwawt/macosx/CInputMethod.java Thu Oct 10 02:35:27 2013 +0400 +++ b/src/macosx/classes/sun/lwawt/macosx/CInputMethod.java Thu Oct 10 11:40:06 2013 +0400 @@ -620,8 +620,7 @@ retString[0] = new String(selectedText); }} }, fAwtFocussedComponent); - } catch (InterruptedException ie) { ie.printStackTrace(); } - catch (InvocationTargetException ite) { ite.printStackTrace(); } + } catch (InvocationTargetException ite) { ite.printStackTrace(); } synchronized(retString) { return retString[0]; } } @@ -669,8 +668,7 @@ }} }, fAwtFocussedComponent); - } catch (InterruptedException ie) { ie.printStackTrace(); } - catch (InvocationTargetException ite) { ite.printStackTrace(); } + } catch (InvocationTargetException ite) { ite.printStackTrace(); } synchronized(returnValue) { return returnValue; } } @@ -695,8 +693,7 @@ returnValue[0] = fIMContext.getInsertPositionOffset(); }} }, fAwtFocussedComponent); - } catch (InterruptedException ie) { ie.printStackTrace(); } - catch (InvocationTargetException ite) { ite.printStackTrace(); } + } catch (InvocationTargetException ite) { ite.printStackTrace(); } returnValue[1] = fCurrentTextLength; synchronized(returnValue) { return returnValue; } @@ -743,8 +740,7 @@ } }} }, fAwtFocussedComponent); - } catch (InterruptedException ie) { ie.printStackTrace(); } - catch (InvocationTargetException ite) { ite.printStackTrace(); } + } catch (InvocationTargetException ite) { ite.printStackTrace(); } synchronized(rect) { return rect; } } @@ -764,8 +760,7 @@ insertPositionOffset[0] = fIMContext.getInsertPositionOffset(); }} }, 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. // If it falls outside that region, the input method will commit the text, which is inconsistent with native
--- a/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java Thu Oct 10 02:35:27 2013 +0400 +++ b/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java Thu Oct 10 11:40:06 2013 +0400 @@ -884,7 +884,7 @@ //Posting an empty to flush the EventQueue without blocking the main thread } }, target); - } catch (InterruptedException | InvocationTargetException e) { + } catch (InvocationTargetException e) { e.printStackTrace(); } }
--- a/src/macosx/classes/sun/lwawt/macosx/CViewEmbeddedFrame.java Thu Oct 10 02:35:27 2013 +0400 +++ b/src/macosx/classes/sun/lwawt/macosx/CViewEmbeddedFrame.java Thu Oct 10 11:40:06 2013 +0400 @@ -97,6 +97,6 @@ setVisible(true); } }, this); - } catch (InterruptedException | InvocationTargetException ex) {} + } catch (InvocationTargetException ex) {} } }
--- a/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java Thu Oct 10 02:35:27 2013 +0400 +++ b/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java Thu Oct 10 11:40:06 2013 +0400 @@ -548,22 +548,18 @@ // 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 // 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(); InvocationEvent invocationEvent = - new InvocationEvent(component != null ? component : Toolkit.getDefaultToolkit(), event) { - @Override - public void dispatch() { - try { - super.dispatch(); - } finally { + new InvocationEvent(component != null ? component : Toolkit.getDefaultToolkit(), + runnable, + () -> { if (mediator != 0) { stopAWTRunLoop(mediator); } - } - } - }; + }, + true); if (component != null) { AppContext appContext = SunToolkit.targetToAppContext(component);
--- a/src/share/classes/java/awt/EventQueue.java Thu Oct 10 02:35:27 2013 +0400 +++ b/src/share/classes/java/awt/EventQueue.java Thu Oct 10 11:40:06 2013 +0400 @@ -1159,6 +1159,10 @@ if (entry.event instanceof SentEvent) { ((SentEvent)entry.event).dispose(); } + if (entry.event instanceof InvocationEvent) { + AWTAccessor.getInvocationEventAccessor() + .dispose((InvocationEvent)entry.event); + } if (prev == null) { queues[i].head = entry.next; } else {
--- a/src/share/classes/java/awt/event/InvocationEvent.java Thu Oct 10 02:35:27 2013 +0400 +++ b/src/share/classes/java/awt/event/InvocationEvent.java Thu Oct 10 11:40:06 2013 +0400 @@ -25,6 +25,8 @@ package java.awt.event; +import sun.awt.AWTAccessor; + import java.awt.ActiveEvent; import java.awt.AWTEvent; @@ -56,6 +58,15 @@ */ 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. */ @@ -78,11 +89,21 @@ /** * 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 */ - 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> @@ -147,7 +168,7 @@ * @see #InvocationEvent(Object, Runnable, Object, boolean) */ public InvocationEvent(Object source, Runnable runnable) { - this(source, runnable, null, false); + this(source, INVOCATION_DEFAULT, runnable, null, null, false); } /** @@ -171,7 +192,8 @@ * @param notifier The {@code Object} whose <code>notifyAll</code> * method will be called after * <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> * should catch Throwable when executing * the <code>Runnable</code>'s <code>run</code> @@ -185,7 +207,39 @@ */ public InvocationEvent(Object source, Runnable runnable, Object notifier, 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 @@ * @param notifier The <code>Object</code> whose <code>notifyAll</code> * method will be called after * <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> * should catch Throwable when executing the * <code>Runnable</code>'s <code>run</code> @@ -221,13 +276,18 @@ */ protected InvocationEvent(Object source, int id, Runnable runnable, 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); this.runnable = runnable; this.notifier = notifier; + this.listener = listener; this.catchExceptions = catchThrowables; this.when = System.currentTimeMillis(); } - /** * Executes the Runnable's <code>run()</code> method and notifies the * notifier (if any) when <code>run()</code> has returned or thrown an exception. @@ -251,13 +311,7 @@ runnable.run(); } } finally { - dispatched = true; - - if (notifier != null) { - synchronized (notifier) { - notifier.notifyAll(); - } - } + finishedDispatching(true); } } @@ -331,6 +385,25 @@ } /** + * 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. * This method is useful for event-logging and for debugging. *
--- a/src/share/classes/sun/awt/AWTAccessor.java Thu Oct 10 02:35:27 2013 +0400 +++ b/src/share/classes/sun/awt/AWTAccessor.java Thu Oct 10 11:40:06 2013 +0400 @@ -31,6 +31,7 @@ import java.awt.KeyboardFocusManager; import java.awt.DefaultKeyboardFocusManager; import java.awt.event.InputEvent; +import java.awt.event.InvocationEvent; import java.awt.event.KeyEvent; import java.awt.geom.Point2D; import java.awt.peer.ComponentPeer; @@ -721,6 +722,13 @@ } /* + * An accessor object for the InvocationEvent class + */ + public interface InvocationEventAccessor { + void dispose(InvocationEvent event); + } + + /* * Accessor instances are initialized in the static initializers of * corresponding AWT classes by using setters defined below. */ @@ -748,6 +756,7 @@ private static DefaultKeyboardFocusManagerAccessor defaultKeyboardFocusManagerAccessor; private static SequencedEventAccessor sequencedEventAccessor; private static ToolkitAccessor toolkitAccessor; + private static InvocationEventAccessor invocationEventAccessor; /* * Set an accessor object for the java.awt.Component class. @@ -1159,4 +1168,18 @@ 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; + } }