Hi, A couple of drawing operations on CairoGraphics2D are implemented by calling other drawing primitives. This means that a draw() might call fill() later on for example. Since ComponentGraphics needs to acquire the gdk lock before actually doing any drawing (through its super class CairoGraphics2D) we would sometimes get a deadlock since the gdk lock isn't reentrant. This patch makes the ComponentGraphics lock reentrant by using a ThreadLocal that counts the number of locks and unlocks on a particular Thread and only actually takes the gdk lock or releases it when the count drops to zero.
2006-06-12 Mark Wielaard <[EMAIL PROTECTED]>
* gnu/java/awt/peer/gtk/ComponentGraphics.java (hasLock):
New static field.
(ONE): Likewise.
(lock): New method.
(unlock): Likewise.
(draw): Use lock() and unlock().
(fill): Likewise.
(drawRenderedImage): Likewise.
(drawImage): Likewise.
(drawGlyphVector): Likewise.
I was a bit afraid this would impact drawing a lot, but I personally
don't notice any slowdown when using things. Since it solve some real
deadlocks for me I am checking this in.
Cheers,
Mark
Index: gnu/java/awt/peer/gtk/ComponentGraphics.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/java/awt/peer/gtk/ComponentGraphics.java,v
retrieving revision 1.13
diff -u -r1.13 ComponentGraphics.java
--- gnu/java/awt/peer/gtk/ComponentGraphics.java 11 Jun 2006 11:21:52 -0000 1.13
+++ gnu/java/awt/peer/gtk/ComponentGraphics.java 12 Jun 2006 12:15:34 -0000
@@ -67,6 +67,35 @@
private GtkComponentPeer component;
protected long cairo_t;
+ private static ThreadLocal hasLock = new ThreadLocal();
+ private static Integer ONE = Integer.valueOf(1);
+
+ private void lock()
+ {
+ Integer i = (Integer) hasLock.get();
+ if (i == null)
+ {
+ start_gdk_drawing();
+ hasLock.set(ONE);
+ }
+ else
+ hasLock.set(Integer.valueOf(i.intValue() + 1));
+ }
+
+ private void unlock()
+ {
+ Integer i = (Integer) hasLock.get();
+ if (i == null)
+ throw new IllegalStateException();
+ if (i == ONE)
+ {
+ hasLock.set(null);
+ end_gdk_drawing();
+ }
+ else
+ hasLock.set(Integer.valueOf(i.intValue() - 1));
+ }
+
ComponentGraphics()
{
}
@@ -180,40 +209,40 @@
*/
public void draw(Shape s)
{
- start_gdk_drawing();
+ lock();
try
{
super.draw(s);
}
finally
{
- end_gdk_drawing();
+ unlock();
}
}
public void fill(Shape s)
{
- start_gdk_drawing();
+ lock();
try
{
super.fill(s);
}
finally
{
- end_gdk_drawing();
+ unlock();
}
}
public void drawRenderedImage(RenderedImage image, AffineTransform xform)
{
- start_gdk_drawing();
+ lock();
try
{
super.drawRenderedImage(image, xform);
}
finally
{
- end_gdk_drawing();
+ unlock();
}
}
@@ -221,28 +250,28 @@
Color bgcolor, ImageObserver obs)
{
boolean rv;
- start_gdk_drawing();
+ lock();
try
{
rv = super.drawImage(img, xform, bgcolor, obs);
}
finally
{
- end_gdk_drawing();
+ unlock();
}
return rv;
}
public void drawGlyphVector(GlyphVector gv, float x, float y)
{
- start_gdk_drawing();
+ lock();
try
{
super.drawGlyphVector(gv, x, y);
}
finally
{
- end_gdk_drawing();
+ unlock();
}
}
signature.asc
Description: This is a digitally signed message part
