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

7192977: Issue in toolkit thread

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