mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-07 17:56:01 +02:00
Bug 330838: Protect writable index against usage in multiple threads.
This commit is contained in:
parent
6cab1923dc
commit
9792e732c4
2 changed files with 26 additions and 6 deletions
|
@ -25,7 +25,8 @@ import org.eclipse.cdt.internal.core.pdom.YieldableIndexLock;
|
|||
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
|
||||
*/
|
||||
|
|
|
@ -26,6 +26,7 @@ public class WritableCIndex extends CIndex implements IWritableIndex {
|
|||
|
||||
final private IWritableIndexFragment fWritableFragment;
|
||||
private boolean fIsWriteLocked= false;
|
||||
private Object fThread;
|
||||
|
||||
public WritableCIndex(IWritableIndexFragment writable, IIndexFragment[] readonly) {
|
||||
super (concat(writable, readonly));
|
||||
|
@ -106,18 +107,23 @@ public class WritableCIndex extends CIndex implements IWritableIndex {
|
|||
}
|
||||
|
||||
@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$
|
||||
super.acquireReadLock();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void releaseReadLock() {
|
||||
public void releaseReadLock() {
|
||||
checkThread();
|
||||
assert !fIsWriteLocked: "Read locks are not allowed while write-locked."; //$NON-NLS-1$
|
||||
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 giveupReadlockCount == getReadLockCount(): "Unexpected read lock is not allowed"; //$NON-NLS-1$
|
||||
|
||||
|
@ -125,11 +131,12 @@ public class WritableCIndex extends CIndex implements IWritableIndex {
|
|||
fIsWriteLocked= true;
|
||||
}
|
||||
|
||||
public synchronized void releaseWriteLock(int establishReadlockCount) {
|
||||
public void releaseWriteLock(int establishReadlockCount) {
|
||||
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 establishReadlockCount == getReadLockCount(): "Unexpected read lock is not allowed"; //$NON-NLS-1$
|
||||
|
||||
|
@ -140,8 +147,20 @@ public class WritableCIndex extends CIndex implements IWritableIndex {
|
|||
|
||||
fIsWriteLocked= false;
|
||||
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
|
||||
public void clearResultCache() {
|
||||
assert fIsWriteLocked: "Need to hold a write lock to clear result caches"; //$NON-NLS-1$
|
||||
|
|
Loading…
Add table
Reference in a new issue