Hi,
While testing various applications I found a race condition in
GtkComponentPeer paintArea. We try to coalesce paint events and updating
that area. The paint and update Component methods need to get the
current paint area and reset it before actually using it, so event
coming in during painting and updating don't interfere.
2006-12-03 Mark Wielaard <[EMAIL PROTECTED]>
* gnu/java/awt/peer/gtk/GtkComponentPeer.java (paintArea): Renamed
to currentPaintArea.
(paintComponent): Work with local reference to currentPaintArea.
(updateComponent): Likewise.
(coalescePaintEvent): Set currentPaintArea.
Committed,
Mark
Index: gnu/java/awt/peer/gtk/GtkComponentPeer.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/java/awt/peer/gtk/GtkComponentPeer.java,v
retrieving revision 1.122
diff -u -r1.122 GtkComponentPeer.java
--- gnu/java/awt/peer/gtk/GtkComponentPeer.java 29 Nov 2006 12:56:39 -0000 1.122
+++ gnu/java/awt/peer/gtk/GtkComponentPeer.java 3 Dec 2006 15:57:03 -0000
@@ -91,9 +91,9 @@
Insets insets;
/**
- * The current repaint area.
+ * The current repaint area. Use should be guarded by synchronizing on this.
*/
- protected Rectangle paintArea;
+ private Rectangle currentPaintArea;
/* this isEnabled differs from Component.isEnabled, in that it
knows if a parent is disabled. In that case Component.isEnabled
@@ -313,7 +313,14 @@
// seems expensive. However, the graphics state does not carry
// over between calls to paint, and resetting the graphics object
// may even be more costly than simply creating a new one.
- synchronized (paintArea)
+ Rectangle paintArea;
+ synchronized (this)
+ {
+ paintArea = currentPaintArea;
+ currentPaintArea = null;
+ }
+
+ if (paintArea != null)
{
Graphics g = getGraphics();
try
@@ -324,7 +331,6 @@
finally
{
g.dispose();
- paintArea = null;
}
}
}
@@ -339,7 +345,14 @@
|| (awtComponent.getWidth() < 1 || awtComponent.getHeight() < 1))
return;
- synchronized (paintArea)
+ Rectangle paintArea;
+ synchronized (this)
+ {
+ paintArea = currentPaintArea;
+ currentPaintArea = null;
+ }
+
+ if (paintArea != null)
{
Graphics g = getGraphics();
try
@@ -350,7 +363,6 @@
finally
{
g.dispose();
- paintArea = null;
}
}
}
@@ -776,10 +788,10 @@
synchronized (this)
{
Rectangle newRect = e.getUpdateRect();
- if (paintArea == null)
- paintArea = newRect;
+ if (currentPaintArea == null)
+ currentPaintArea = newRect;
else
- Rectangle.union(paintArea, newRect, paintArea);
+ Rectangle.union(currentPaintArea, newRect, currentPaintArea);
}
}