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:
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;
|
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
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Reference in a new issue