This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
Patch FYI: Fix PR libgcj/21557
- From: Bryce McKinlay <mckinlay at redhat dot com>
- To: java-patches at gcc dot gnu dot org
- Date: Fri, 13 May 2005 20:23:38 -0400
- Subject: Patch FYI: Fix PR libgcj/21557
This patch fixes PR libgcj/21557.
_Jv_MonitorEnter uses _Jv_Condwait when it needs to expand a lock to
heavyweight status due to contention. If the thread is interrupted with
Thread.interrupt() before or during the lock expansion process,
_Jv_Condwait will return _JV_INTERRUTPED. Because _Jv_MonitorEnter did
not check for this return value, an infinite loop would result.
This patch fixes the problem by checking for the _JV_INTERRUPTED return
value and clearing the thread's interrupted status flag. It also
restores the flag once the lock has been successfully converted.
I'm checking this in to both the HEAD and branch.
Bryce
2005-05-13 Bryce McKinlay <mckinlay@redhat.com>
PR libgcj/21557
* java/lang/natObject.cc (_Jv_MonitorEnter): Save and clear thread
interrupt status flag if _Jv_CondWait is interrupted.
Index: java/lang/natObject.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/lang/natObject.cc,v
retrieving revision 1.33
diff -u -r1.33 natObject.cc
--- java/lang/natObject.cc 5 Jan 2005 05:09:09 -0000 1.33
+++ java/lang/natObject.cc 14 May 2005 00:16:21 -0000
@@ -35,6 +35,8 @@
+using namespace java::lang;
+
// This is used to represent synchronization information.
struct _Jv_SyncInfo
{
@@ -926,12 +928,22 @@
release_set(&(he -> address), (address | REQUEST_CONVERSION | HEAVY));
// release lock on he
LOG(REQ_CONV, (address | REQUEST_CONVERSION | HEAVY), self);
+ // If _Jv_CondWait is interrupted, we ignore the interrupt, but
+ // restore the thread's interrupt status flag when done.
+ jboolean interrupt_flag = false;
while ((he -> address & ~FLAGS) == (address & ~FLAGS))
{
// Once converted, the lock has to retain heavyweight
- // status, since heavy_count > 0 .
- _Jv_CondWait (&(hl->si.condition), &(hl->si.mutex), 0, 0);
+ // status, since heavy_count > 0.
+ int r = _Jv_CondWait (&(hl->si.condition), &(hl->si.mutex), 0, 0);
+ if (r == _JV_INTERRUPTED)
+ {
+ interrupt_flag = true;
+ Thread::currentThread()->interrupt_flag = false;
+ }
}
+ if (interrupt_flag)
+ Thread::currentThread()->interrupt_flag = interrupt_flag;
keep_live(addr);
// Guarantee that hl doesn't get unlinked by finalizer.
// This is only an issue if the client fails to release