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:
parent
a8ced8a5d3
commit
829bdef1da
2 changed files with 68 additions and 10 deletions
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue