1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-14 19:55:45 +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(); 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 { public void acquireReadLock() throws InterruptedException {
synchronized (mutex) { synchronized (mutex) {
++waitingReaders; ++waitingReaders;
try {
while (lockCount < 0) while (lockCount < 0)
mutex.wait(); mutex.wait();
}
finally {
--waitingReaders; --waitingReaders;
}
++lockCount; ++lockCount;
} }
} }
@ -530,18 +534,18 @@ public class PDOM extends PlatformObject implements IIndexFragment, IPDOM {
if (giveupReadLocks > 0) { if (giveupReadLocks > 0) {
// giveup on read locks // giveup on read locks
assert lockCount >= giveupReadLocks: "Not enough locks to release"; //$NON-NLS-1$ assert lockCount >= giveupReadLocks: "Not enough locks to release"; //$NON-NLS-1$
if (lockCount >= giveupReadLocks) { if (lockCount < giveupReadLocks) {
lockCount-= giveupReadLocks; giveupReadLocks= lockCount;
} }
else if (lockCount >= 0) {
lockCount= 0;
} }
else {
giveupReadLocks= 0;
} }
// Let the readers go first // Let the readers go first
while (lockCount != 0 || waitingReaders > 0) while (lockCount > giveupReadLocks || waitingReaders > 0)
mutex.wait(); mutex.wait();
--lockCount; lockCount= -1;
db.setWritable(); db.setWritable();
} }
} }