diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/PDOMBugsTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/PDOMBugsTest.java index 1b1d79a1805..b07a836d4db 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/PDOMBugsTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/PDOMBugsTest.java @@ -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(); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java index 8ae4a6ddc5d..a2b94dc7f31 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java @@ -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(); } }