mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-14 11:45: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();
|
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 {
|
public void acquireReadLock() throws InterruptedException {
|
||||||
synchronized (mutex) {
|
synchronized (mutex) {
|
||||||
++waitingReaders;
|
++waitingReaders;
|
||||||
while (lockCount < 0)
|
try {
|
||||||
mutex.wait();
|
while (lockCount < 0)
|
||||||
--waitingReaders;
|
mutex.wait();
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
--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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue