提交 4a3d261b 编写于 作者: B bagiras

7192977: Issue in toolkit thread

Reviewed-by: skoivu, rupashka, art
上级 328a3926
...@@ -194,7 +194,8 @@ public class EventQueue { ...@@ -194,7 +194,8 @@ public class EventQueue {
} }
public void removeSourceEvents(EventQueue eventQueue, public void removeSourceEvents(EventQueue eventQueue,
Object source, Object source,
boolean removeAllEvents) { boolean removeAllEvents)
{
eventQueue.removeSourceEvents(source, removeAllEvents); eventQueue.removeSourceEvents(source, removeAllEvents);
} }
public boolean noEvents(EventQueue eventQueue) { public boolean noEvents(EventQueue eventQueue) {
...@@ -203,6 +204,11 @@ public class EventQueue { ...@@ -203,6 +204,11 @@ public class EventQueue {
public void wakeup(EventQueue eventQueue, boolean isShutdown) { public void wakeup(EventQueue eventQueue, boolean isShutdown) {
eventQueue.wakeup(isShutdown); eventQueue.wakeup(isShutdown);
} }
public void invokeAndWait(Object source, Runnable r)
throws InterruptedException, InvocationTargetException
{
EventQueue.invokeAndWait(source, r);
}
}); });
} }
...@@ -1245,8 +1251,14 @@ public class EventQueue { ...@@ -1245,8 +1251,14 @@ public class EventQueue {
* @since 1.2 * @since 1.2
*/ */
public static void invokeAndWait(Runnable runnable) public static void invokeAndWait(Runnable runnable)
throws InterruptedException, InvocationTargetException { throws InterruptedException, InvocationTargetException
{
invokeAndWait(Toolkit.getDefaultToolkit(), runnable);
}
static void invokeAndWait(Object source, Runnable runnable)
throws InterruptedException, InvocationTargetException
{
if (EventQueue.isDispatchThread()) { if (EventQueue.isDispatchThread()) {
throw new Error("Cannot call invokeAndWait from the event dispatcher thread"); throw new Error("Cannot call invokeAndWait from the event dispatcher thread");
} }
...@@ -1255,8 +1267,7 @@ public class EventQueue { ...@@ -1255,8 +1267,7 @@ public class EventQueue {
Object lock = new AWTInvocationLock(); Object lock = new AWTInvocationLock();
InvocationEvent event = InvocationEvent event =
new InvocationEvent(Toolkit.getDefaultToolkit(), runnable, lock, new InvocationEvent(source, runnable, lock, true);
true);
synchronized (lock) { synchronized (lock) {
Toolkit.getEventQueue().postEvent(event); Toolkit.getEventQueue().postEvent(event);
......
...@@ -1206,7 +1206,7 @@ public class Window extends Container implements Accessible { ...@@ -1206,7 +1206,7 @@ public class Window extends Container implements Accessible {
} }
else { else {
try { try {
EventQueue.invokeAndWait(action); EventQueue.invokeAndWait(this, action);
} }
catch (InterruptedException e) { catch (InterruptedException e) {
System.err.println("Disposal was interrupted:"); System.err.println("Disposal was interrupted:");
......
...@@ -27,11 +27,12 @@ package javax.swing; ...@@ -27,11 +27,12 @@ package javax.swing;
import java.awt.*; import java.awt.*;
import java.awt.event.*; import java.awt.event.*;
import java.awt.peer.ComponentPeer;
import java.awt.peer.ContainerPeer;
import java.awt.image.VolatileImage; import java.awt.image.VolatileImage;
import java.security.AccessControlContext;
import java.security.AccessController; import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.*; import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.applet.*; import java.applet.*;
import sun.awt.AWTAccessor; import sun.awt.AWTAccessor;
...@@ -39,6 +40,8 @@ import sun.awt.AppContext; ...@@ -39,6 +40,8 @@ import sun.awt.AppContext;
import sun.awt.DisplayChangedListener; import sun.awt.DisplayChangedListener;
import sun.awt.SunToolkit; import sun.awt.SunToolkit;
import sun.java2d.SunGraphicsEnvironment; import sun.java2d.SunGraphicsEnvironment;
import sun.misc.JavaSecurityAccess;
import sun.misc.SharedSecrets;
import sun.security.action.GetPropertyAction; import sun.security.action.GetPropertyAction;
import com.sun.java.swing.SwingUtilities3; import com.sun.java.swing.SwingUtilities3;
...@@ -176,6 +179,9 @@ public class RepaintManager ...@@ -176,6 +179,9 @@ public class RepaintManager
*/ */
private final ProcessingRunnable processingRunnable; private final ProcessingRunnable processingRunnable;
private final static JavaSecurityAccess javaSecurityAccess =
SharedSecrets.getJavaSecurityAccess();
static { static {
volatileImageBufferEnabled = "true".equals(AccessController. volatileImageBufferEnabled = "true".equals(AccessController.
...@@ -548,13 +554,26 @@ public class RepaintManager ...@@ -548,13 +554,26 @@ public class RepaintManager
// This is called from the toolkit thread when awt needs to run a // This is called from the toolkit thread when awt needs to run a
// Runnable before we paint. // Runnable before we paint.
// //
void nativeQueueSurfaceDataRunnable(AppContext appContext, Component c, void nativeQueueSurfaceDataRunnable(AppContext appContext,
Runnable r) { final Component c, final Runnable r)
{
synchronized(this) { synchronized(this) {
if (runnableList == null) { if (runnableList == null) {
runnableList = new LinkedList<Runnable>(); runnableList = new LinkedList<Runnable>();
} }
runnableList.add(r); runnableList.add(new Runnable() {
public void run() {
AccessControlContext stack = AccessController.getContext();
AccessControlContext acc =
AWTAccessor.getComponentAccessor().getAccessControlContext(c);
javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Void>() {
public Void run() {
r.run();
return null;
}
}, stack, acc);
}
});
} }
scheduleProcessingRunnable(appContext); scheduleProcessingRunnable(appContext);
} }
...@@ -652,9 +671,9 @@ public class RepaintManager ...@@ -652,9 +671,9 @@ public class RepaintManager
* @see #addInvalidComponent * @see #addInvalidComponent
*/ */
public void validateInvalidComponents() { public void validateInvalidComponents() {
java.util.List<Component> ic; final java.util.List<Component> ic;
synchronized(this) { synchronized(this) {
if(invalidComponents == null) { if (invalidComponents == null) {
return; return;
} }
ic = invalidComponents; ic = invalidComponents;
...@@ -662,7 +681,17 @@ public class RepaintManager ...@@ -662,7 +681,17 @@ public class RepaintManager
} }
int n = ic.size(); int n = ic.size();
for(int i = 0; i < n; i++) { for(int i = 0; i < n; i++) {
ic.get(i).validate(); final Component c = ic.get(i);
AccessControlContext stack = AccessController.getContext();
AccessControlContext acc =
AWTAccessor.getComponentAccessor().getAccessControlContext(c);
javaSecurityAccess.doIntersectionPrivilege(
new PrivilegedAction<Void>() {
public Void run() {
c.validate();
return null;
}
}, stack, acc);
} }
} }
...@@ -740,78 +769,78 @@ public class RepaintManager ...@@ -740,78 +769,78 @@ public class RepaintManager
paintDirtyRegions(tmpDirtyComponents); paintDirtyRegions(tmpDirtyComponents);
} }
private void paintDirtyRegions(Map<Component,Rectangle> private void paintDirtyRegions(
tmpDirtyComponents){ final Map<Component,Rectangle> tmpDirtyComponents)
int i, count; {
java.util.List<Component> roots; if (tmpDirtyComponents.isEmpty()) {
Component dirtyComponent;
count = tmpDirtyComponents.size();
if (count == 0) {
return; return;
} }
Rectangle rect; final java.util.List<Component> roots =
int localBoundsX = 0; new ArrayList<Component>(tmpDirtyComponents.size());
int localBoundsY = 0;
int localBoundsH;
int localBoundsW;
roots = new ArrayList<Component>(count);
for (Component dirty : tmpDirtyComponents.keySet()) { for (Component dirty : tmpDirtyComponents.keySet()) {
collectDirtyComponents(tmpDirtyComponents, dirty, roots); collectDirtyComponents(tmpDirtyComponents, dirty, roots);
} }
count = roots.size(); final AtomicInteger count = new AtomicInteger(roots.size());
painting = true; painting = true;
try { try {
for(i=0 ; i < count ; i++) { for (int j=0 ; j < count.get(); j++) {
dirtyComponent = roots.get(i); final int i = j;
rect = tmpDirtyComponents.get(dirtyComponent); final Component dirtyComponent = roots.get(j);
// Sometimes when RepaintManager is changed during the painting AccessControlContext stack = AccessController.getContext();
// we may get null here, see #6995769 for details AccessControlContext acc =
if (rect == null) { AWTAccessor.getComponentAccessor().getAccessControlContext(dirtyComponent);
continue; javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Void>() {
} public Void run() {
localBoundsH = dirtyComponent.getHeight(); Rectangle rect = tmpDirtyComponents.get(dirtyComponent);
localBoundsW = dirtyComponent.getWidth(); // Sometimes when RepaintManager is changed during the painting
// we may get null here, see #6995769 for details
SwingUtilities.computeIntersection(localBoundsX, if (rect == null) {
localBoundsY, return null;
localBoundsW, }
localBoundsH,
rect); int localBoundsH = dirtyComponent.getHeight();
if (dirtyComponent instanceof JComponent) { int localBoundsW = dirtyComponent.getWidth();
((JComponent)dirtyComponent).paintImmediately( SwingUtilities.computeIntersection(0,
rect.x,rect.y,rect.width, rect.height); 0,
} localBoundsW,
else if (dirtyComponent.isShowing()) { localBoundsH,
Graphics g = JComponent.safelyGetGraphics( rect);
dirtyComponent, dirtyComponent); if (dirtyComponent instanceof JComponent) {
// If the Graphics goes away, it means someone disposed of ((JComponent)dirtyComponent).paintImmediately(
// the window, don't do anything. rect.x,rect.y,rect.width, rect.height);
if (g != null) { }
g.setClip(rect.x, rect.y, rect.width, rect.height); else if (dirtyComponent.isShowing()) {
try { Graphics g = JComponent.safelyGetGraphics(
dirtyComponent.paint(g); dirtyComponent, dirtyComponent);
} finally { // If the Graphics goes away, it means someone disposed of
g.dispose(); // the window, don't do anything.
if (g != null) {
g.setClip(rect.x, rect.y, rect.width, rect.height);
try {
dirtyComponent.paint(g);
} finally {
g.dispose();
}
}
} }
// If the repaintRoot has been set, service it now and
// remove any components that are children of repaintRoot.
if (repaintRoot != null) {
adjustRoots(repaintRoot, roots, i + 1);
count.set(roots.size());
paintManager.isRepaintingRoot = true;
repaintRoot.paintImmediately(0, 0, repaintRoot.getWidth(),
repaintRoot.getHeight());
paintManager.isRepaintingRoot = false;
// Only service repaintRoot once.
repaintRoot = null;
}
return null;
} }
} }, stack, acc);
// If the repaintRoot has been set, service it now and
// remove any components that are children of repaintRoot.
if (repaintRoot != null) {
adjustRoots(repaintRoot, roots, i + 1);
count = roots.size();
paintManager.isRepaintingRoot = true;
repaintRoot.paintImmediately(0, 0, repaintRoot.getWidth(),
repaintRoot.getHeight());
paintManager.isRepaintingRoot = false;
// Only service repaintRoot once.
repaintRoot = null;
}
} }
} finally { } finally {
painting = false; painting = false;
......
...@@ -45,6 +45,7 @@ import java.util.*; ...@@ -45,6 +45,7 @@ import java.util.*;
import java.util.Collections; import java.util.Collections;
import java.util.Locale; import java.util.Locale;
import java.util.WeakHashMap; import java.util.WeakHashMap;
import sun.awt.AWTAccessor;
import sun.awt.AppContext; import sun.awt.AppContext;
import sun.awt.EmbeddedFrame; import sun.awt.EmbeddedFrame;
import sun.awt.SunToolkit; import sun.awt.SunToolkit;
...@@ -448,12 +449,12 @@ abstract class AppletPanel extends Panel implements AppletStub, Runnable { ...@@ -448,12 +449,12 @@ abstract class AppletPanel extends Panel implements AppletStub, Runnable {
// to avoid deadlock. // to avoid deadlock.
try { try {
final AppletPanel p = this; final AppletPanel p = this;
Runnable r = new Runnable() {
EventQueue.invokeAndWait(new Runnable() { public void run() {
public void run() { p.validate();
p.validate(); }
} };
}); AWTAccessor.getEventQueueAccessor().invokeAndWait(applet, r);
} }
catch(InterruptedException ie) { catch(InterruptedException ie) {
} }
...@@ -478,18 +479,19 @@ abstract class AppletPanel extends Panel implements AppletStub, Runnable { ...@@ -478,18 +479,19 @@ abstract class AppletPanel extends Panel implements AppletStub, Runnable {
try { try {
final AppletPanel p = this; final AppletPanel p = this;
final Applet a = applet; final Applet a = applet;
Runnable r = new Runnable() {
EventQueue.invokeAndWait(new Runnable() { public void run() {
public void run() { p.validate();
p.validate(); a.setVisible(true);
a.setVisible(true);
// Fix for BugTraq ID 4041703.
// Fix for BugTraq ID 4041703. // Set the default focus for an applet.
// Set the default focus for an applet. if (hasInitialFocus()) {
if (hasInitialFocus()) setDefaultFocus();
setDefaultFocus();
} }
}); }
};
AWTAccessor.getEventQueueAccessor().invokeAndWait(applet, r);
} }
catch(InterruptedException ie) { catch(InterruptedException ie) {
} }
...@@ -512,13 +514,12 @@ abstract class AppletPanel extends Panel implements AppletStub, Runnable { ...@@ -512,13 +514,12 @@ abstract class AppletPanel extends Panel implements AppletStub, Runnable {
// to avoid deadlock. // to avoid deadlock.
try { try {
final Applet a = applet; final Applet a = applet;
Runnable r = new Runnable() {
EventQueue.invokeAndWait(new Runnable() { public void run() {
public void run() a.setVisible(false);
{ }
a.setVisible(false); };
} AWTAccessor.getEventQueueAccessor().invokeAndWait(applet, r);
});
} }
catch(InterruptedException ie) { catch(InterruptedException ie) {
} }
...@@ -570,17 +571,14 @@ abstract class AppletPanel extends Panel implements AppletStub, Runnable { ...@@ -570,17 +571,14 @@ abstract class AppletPanel extends Panel implements AppletStub, Runnable {
} }
status = APPLET_DISPOSE; status = APPLET_DISPOSE;
try try {
{
final Applet a = applet; final Applet a = applet;
Runnable r = new Runnable() {
EventQueue.invokeAndWait(new Runnable() public void run() {
{
public void run()
{
remove(a); remove(a);
} }
}); };
AWTAccessor.getEventQueueAccessor().invokeAndWait(applet, r);
} }
catch(InterruptedException ie) catch(InterruptedException ie)
{ {
......
...@@ -34,6 +34,8 @@ import java.awt.event.InputEvent; ...@@ -34,6 +34,8 @@ import java.awt.event.InputEvent;
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;
import java.lang.reflect.InvocationTargetException;
import java.security.AccessControlContext; import java.security.AccessControlContext;
import java.io.File; import java.io.File;
...@@ -476,6 +478,12 @@ public final class AWTAccessor { ...@@ -476,6 +478,12 @@ public final class AWTAccessor {
* appeared. * appeared.
*/ */
void wakeup(EventQueue eventQueue, boolean isShutdown); void wakeup(EventQueue eventQueue, boolean isShutdown);
/**
* Static in EventQueue
*/
void invokeAndWait(Object source, Runnable r)
throws InterruptedException, InvocationTargetException;
} }
/* /*
......
...@@ -488,14 +488,15 @@ public abstract class WComponentPeer extends WObjectPeer ...@@ -488,14 +488,15 @@ public abstract class WComponentPeer extends WObjectPeer
try { try {
replaceSurfaceData(); replaceSurfaceData();
} catch (InvalidPipeException e) { } catch (InvalidPipeException e) {
// REMIND : what do we do if our surface creation failed? // REMIND : what do we do if our surface creation failed?
} }
} }
} }
}; };
Component c = (Component)target;
// Fix 6255371. // Fix 6255371.
if (!PaintEventDispatcher.getPaintEventDispatcher().queueSurfaceDataReplacing((Component)target, r)) { if (!PaintEventDispatcher.getPaintEventDispatcher().queueSurfaceDataReplacing(c, r)) {
postEvent(new InvocationEvent(Toolkit.getDefaultToolkit(), r)); postEvent(new InvocationEvent(c, r));
} }
} }
...@@ -618,7 +619,7 @@ public abstract class WComponentPeer extends WObjectPeer ...@@ -618,7 +619,7 @@ public abstract class WComponentPeer extends WObjectPeer
} }
public void disposeLater() { public void disposeLater() {
postEvent(new InvocationEvent(Toolkit.getDefaultToolkit(), new Runnable() { postEvent(new InvocationEvent(target, new Runnable() {
public void run() { public void run() {
dispose(); dispose();
} }
......
...@@ -27,6 +27,7 @@ package sun.awt.windows; ...@@ -27,6 +27,7 @@ package sun.awt.windows;
import sun.awt.*; import sun.awt.*;
import java.awt.*; import java.awt.*;
import java.awt.event.InvocationEvent;
import java.awt.peer.ComponentPeer; import java.awt.peer.ComponentPeer;
import java.awt.image.*; import java.awt.image.*;
import sun.awt.image.ByteInterleavedRaster; import sun.awt.image.ByteInterleavedRaster;
...@@ -232,11 +233,13 @@ public class WEmbeddedFrame extends EmbeddedFrame { ...@@ -232,11 +233,13 @@ public class WEmbeddedFrame extends EmbeddedFrame {
} else { } else {
// To avoid focus concurrence b/w IE and EmbeddedFrame // To avoid focus concurrence b/w IE and EmbeddedFrame
// activation is postponed by means of posting it to EDT. // activation is postponed by means of posting it to EDT.
EventQueue.invokeLater(new Runnable() { Runnable r = new Runnable() {
public void run() { public void run() {
((WEmbeddedFramePeer)getPeer()).synthesizeWmActivate(true); ((WEmbeddedFramePeer)getPeer()).synthesizeWmActivate(true);
} }
}); };
WToolkit.postEvent(WToolkit.targetToAppContext(this),
new InvocationEvent(this, r));
} }
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册