8025588: [macosx] Frozen AppKit thread in 7u40
Reviewed-by: anthony, art, serb
This commit is contained in:
parent
1f3355acb3
commit
dafa242f76
@ -620,8 +620,7 @@ public class CInputMethod extends InputMethodAdapter {
|
||||
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 @@ public class CInputMethod extends InputMethodAdapter {
|
||||
|
||||
}}
|
||||
}, fAwtFocussedComponent);
|
||||
} catch (InterruptedException ie) { ie.printStackTrace(); }
|
||||
catch (InvocationTargetException ite) { ite.printStackTrace(); }
|
||||
} catch (InvocationTargetException ite) { ite.printStackTrace(); }
|
||||
|
||||
synchronized(returnValue) { return returnValue; }
|
||||
}
|
||||
@ -695,8 +693,7 @@ public class CInputMethod extends InputMethodAdapter {
|
||||
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 @@ public class CInputMethod extends InputMethodAdapter {
|
||||
}
|
||||
}}
|
||||
}, fAwtFocussedComponent);
|
||||
} catch (InterruptedException ie) { ie.printStackTrace(); }
|
||||
catch (InvocationTargetException ite) { ite.printStackTrace(); }
|
||||
} catch (InvocationTargetException ite) { ite.printStackTrace(); }
|
||||
|
||||
synchronized(rect) { return rect; }
|
||||
}
|
||||
@ -764,8 +760,7 @@ public class CInputMethod extends InputMethodAdapter {
|
||||
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
|
||||
|
@ -884,7 +884,7 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
|
||||
//Posting an empty to flush the EventQueue without blocking the main thread
|
||||
}
|
||||
}, target);
|
||||
} catch (InterruptedException | InvocationTargetException e) {
|
||||
} catch (InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
@ -97,6 +97,6 @@ public class CViewEmbeddedFrame extends EmbeddedFrame {
|
||||
setVisible(true);
|
||||
}
|
||||
}, this);
|
||||
} catch (InterruptedException | InvocationTargetException ex) {}
|
||||
} catch (InvocationTargetException ex) {}
|
||||
}
|
||||
}
|
||||
|
@ -548,22 +548,18 @@ public final class LWCToolkit extends LWToolkit {
|
||||
// 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);
|
||||
|
@ -1159,6 +1159,10 @@ public class EventQueue {
|
||||
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 {
|
||||
|
@ -25,6 +25,8 @@
|
||||
|
||||
package java.awt.event;
|
||||
|
||||
import sun.awt.AWTAccessor;
|
||||
|
||||
import java.awt.ActiveEvent;
|
||||
import java.awt.AWTEvent;
|
||||
|
||||
@ -56,6 +58,15 @@ import java.awt.AWTEvent;
|
||||
*/
|
||||
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 @@ public class InvocationEvent extends AWTEvent implements ActiveEvent {
|
||||
|
||||
/**
|
||||
* 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 @@ public class InvocationEvent extends AWTEvent implements ActiveEvent {
|
||||
* @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 @@ public class InvocationEvent extends AWTEvent implements ActiveEvent {
|
||||
* @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 class InvocationEvent extends AWTEvent implements ActiveEvent {
|
||||
*/
|
||||
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 @@ public class InvocationEvent extends AWTEvent implements ActiveEvent {
|
||||
* @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 @@ public class InvocationEvent extends AWTEvent implements ActiveEvent {
|
||||
*/
|
||||
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 @@ public class InvocationEvent extends AWTEvent implements ActiveEvent {
|
||||
runnable.run();
|
||||
}
|
||||
} finally {
|
||||
dispatched = true;
|
||||
|
||||
if (notifier != null) {
|
||||
synchronized (notifier) {
|
||||
notifier.notifyAll();
|
||||
}
|
||||
}
|
||||
finishedDispatching(true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -330,6 +384,25 @@ public class InvocationEvent extends AWTEvent implements ActiveEvent {
|
||||
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.
|
||||
* This method is useful for event-logging and for debugging.
|
||||
|
@ -31,6 +31,7 @@ import java.awt.*;
|
||||
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;
|
||||
@ -720,6 +721,13 @@ public final class AWTAccessor {
|
||||
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
|
||||
* corresponding AWT classes by using setters defined below.
|
||||
@ -748,6 +756,7 @@ public final class AWTAccessor {
|
||||
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 @@ public final class AWTAccessor {
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user