1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-08 02:06:01 +02:00

Bug 330838: Protect writable index against usage in multiple threads.

This commit is contained in:
Markus Schorn 2010-12-02 13:37:01 +00:00
parent 6cab1923dc
commit 9792e732c4
2 changed files with 26 additions and 6 deletions

View file

@ -25,7 +25,8 @@ import org.eclipse.cdt.internal.core.pdom.YieldableIndexLock;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
/** /**
* Interface used by the indexer to write to the index. * Interface used by the indexer to write to the index. A writable index is not thread-safe,
* each instance must not be used within more than one thread.
* *
* @since 4.0 * @since 4.0
*/ */

View file

@ -26,6 +26,7 @@ public class WritableCIndex extends CIndex implements IWritableIndex {
final private IWritableIndexFragment fWritableFragment; final private IWritableIndexFragment fWritableFragment;
private boolean fIsWriteLocked= false; private boolean fIsWriteLocked= false;
private Object fThread;
public WritableCIndex(IWritableIndexFragment writable, IIndexFragment[] readonly) { public WritableCIndex(IWritableIndexFragment writable, IIndexFragment[] readonly) {
super (concat(writable, readonly)); super (concat(writable, readonly));
@ -106,18 +107,23 @@ public class WritableCIndex extends CIndex implements IWritableIndex {
} }
@Override @Override
public synchronized void acquireReadLock() throws InterruptedException { public void acquireReadLock() throws InterruptedException {
checkThread();
assert !fIsWriteLocked: "Read locks are not allowed while write-locked."; //$NON-NLS-1$ assert !fIsWriteLocked: "Read locks are not allowed while write-locked."; //$NON-NLS-1$
super.acquireReadLock(); super.acquireReadLock();
} }
@Override @Override
public synchronized void releaseReadLock() { public void releaseReadLock() {
checkThread();
assert !fIsWriteLocked: "Read locks are not allowed while write-locked."; //$NON-NLS-1$ assert !fIsWriteLocked: "Read locks are not allowed while write-locked."; //$NON-NLS-1$
super.releaseReadLock(); super.releaseReadLock();
if (getReadLockCount() == 0)
fThread= null;
} }
public synchronized void acquireWriteLock(int giveupReadlockCount) throws InterruptedException { public void acquireWriteLock(int giveupReadlockCount) throws InterruptedException {
checkThread();
assert !fIsWriteLocked: "Multiple write locks is not allowed"; //$NON-NLS-1$ assert !fIsWriteLocked: "Multiple write locks is not allowed"; //$NON-NLS-1$
assert giveupReadlockCount == getReadLockCount(): "Unexpected read lock is not allowed"; //$NON-NLS-1$ assert giveupReadlockCount == getReadLockCount(): "Unexpected read lock is not allowed"; //$NON-NLS-1$
@ -125,11 +131,12 @@ public class WritableCIndex extends CIndex implements IWritableIndex {
fIsWriteLocked= true; fIsWriteLocked= true;
} }
public synchronized void releaseWriteLock(int establishReadlockCount) { public void releaseWriteLock(int establishReadlockCount) {
releaseWriteLock(establishReadlockCount, true); releaseWriteLock(establishReadlockCount, true);
} }
public synchronized void releaseWriteLock(int establishReadlockCount, boolean flush) { public void releaseWriteLock(int establishReadlockCount, boolean flush) {
checkThread();
assert fIsWriteLocked: "No write lock to be released"; //$NON-NLS-1$ assert fIsWriteLocked: "No write lock to be released"; //$NON-NLS-1$
assert establishReadlockCount == getReadLockCount(): "Unexpected read lock is not allowed"; //$NON-NLS-1$ assert establishReadlockCount == getReadLockCount(): "Unexpected read lock is not allowed"; //$NON-NLS-1$
@ -140,6 +147,18 @@ public class WritableCIndex extends CIndex implements IWritableIndex {
fIsWriteLocked= false; fIsWriteLocked= false;
fWritableFragment.releaseWriteLock(establishReadlockCount, flush); fWritableFragment.releaseWriteLock(establishReadlockCount, flush);
if (establishReadlockCount == 0) {
fThread= null;
}
}
private void checkThread() {
if (fThread == null) {
fThread= Thread.currentThread();
} else if (fThread != Thread.currentThread()) {
throw new IllegalArgumentException("A writable index must not be used from multiple threads."); //$NON-NLS-1$
}
} }
@Override @Override