1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-13 19:25:38 +02:00

Fix and test for potential deadlock interrupting PDOM.acquireXXXLock()

This commit is contained in:
Markus Schorn 2007-04-16 15:13:29 +00:00
parent a8ced8a5d3
commit 829bdef1da
2 changed files with 68 additions and 10 deletions

View file

@ -120,4 +120,58 @@ public class PDOMBugsTest extends BaseTestCase {
pdom.releaseReadLock();
}
}
public void testInterruptingAcquireReadLock() throws Exception {
final PDOM pdom= (PDOM) CCoreInternals.getPDOMManager().getPDOM(cproject);
final boolean[] ok= {false};
pdom.acquireWriteLock();
try {
Thread other= new Thread() {
public void run() {
try {
pdom.acquireReadLock();
} catch (InterruptedException e) {
ok[0]= true;
}
}
};
other.start();
other.interrupt();
other.join();
assertTrue("thread was not interrupted", ok[0]);
}
finally {
pdom.releaseWriteLock();
}
pdom.acquireWriteLock();
pdom.releaseWriteLock();
}
public void testInterruptingAcquireWriteLock() throws Exception {
final PDOM pdom= (PDOM) CCoreInternals.getPDOMManager().getPDOM(cproject);
final boolean[] ok= {false};
pdom.acquireReadLock();
try {
Thread other= new Thread() {
public void run() {
try {
pdom.acquireReadLock();
pdom.acquireWriteLock(1);
} catch (InterruptedException e) {
ok[0]= true;
pdom.releaseReadLock();
}
}
};
other.start();
other.interrupt();
other.join();
assertTrue("thread was not interrupted", ok[0]);
}
finally {
pdom.releaseReadLock();
}
pdom.acquireWriteLock();
pdom.releaseWriteLock();
}
}

View file

@ -504,9 +504,13 @@ public class PDOM extends PlatformObject implements IIndexFragment, IPDOM {
public void acquireReadLock() throws InterruptedException {
synchronized (mutex) {
++waitingReaders;
while (lockCount < 0)
mutex.wait();
--waitingReaders;
try {
while (lockCount < 0)
mutex.wait();
}
finally {
--waitingReaders;
}
++lockCount;
}
}
@ -530,18 +534,18 @@ public class PDOM extends PlatformObject implements IIndexFragment, IPDOM {
if (giveupReadLocks > 0) {
// giveup on read locks
assert lockCount >= giveupReadLocks: "Not enough locks to release"; //$NON-NLS-1$
if (lockCount >= giveupReadLocks) {
lockCount-= giveupReadLocks;
}
else if (lockCount >= 0) {
lockCount= 0;
if (lockCount < giveupReadLocks) {
giveupReadLocks= lockCount;
}
}
else {
giveupReadLocks= 0;
}
// Let the readers go first
while (lockCount != 0 || waitingReaders > 0)
while (lockCount > giveupReadLocks || waitingReaders > 0)
mutex.wait();
--lockCount;
lockCount= -1;
db.setWritable();
}
}