| /******************************************************************************* |
| * Copyright (c) 2006, 2014 Wind River Systems, Inc. and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Markus Schorn - initial API and implementation |
| * Andrew Ferguson (Symbian) |
| * Sergey Prigogin (Google) |
| *******************************************************************************/ |
| package org.eclipse.cdt.internal.core.index; |
| |
| import org.eclipse.cdt.core.dom.ast.IASTName; |
| import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement; |
| import org.eclipse.cdt.core.index.IIndexFileLocation; |
| import org.eclipse.cdt.core.parser.ISignificantMacros; |
| import org.eclipse.cdt.internal.core.pdom.ASTFilePathResolver; |
| import org.eclipse.cdt.internal.core.pdom.YieldableIndexLock; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| |
| public class WritableCIndex extends CIndex implements IWritableIndex { |
| private boolean fIsWriteLocked; |
| private Object fThread; |
| |
| public WritableCIndex(IWritableIndexFragment writable) { |
| super(new IWritableIndexFragment[] { writable }); |
| } |
| |
| @Override |
| public IWritableIndexFragment getWritableFragment() { |
| return (IWritableIndexFragment) getFragments()[0]; |
| } |
| |
| @Override |
| public IIndexFragmentFile getWritableFile(int linkageID, IIndexFileLocation location, |
| ISignificantMacros macroDictionary) throws CoreException { |
| return (IIndexFragmentFile) super.getFile(linkageID, location, macroDictionary); |
| } |
| |
| @Override |
| public IIndexFragmentFile[] getWritableFiles(int linkageID, IIndexFileLocation location) throws CoreException { |
| return getWritableFragment().getFiles(linkageID, location); |
| } |
| |
| @Override |
| public IIndexFragmentFile[] getWritableFiles(IIndexFileLocation location) throws CoreException { |
| return getWritableFragment().getFiles(location); |
| } |
| |
| @Override |
| public IIndexFragmentFile addFile(int linkageID, IIndexFileLocation location, |
| ISignificantMacros macroDictionary) throws CoreException { |
| return getWritableFragment().addFile(linkageID, location, macroDictionary); |
| } |
| |
| @Override |
| public IIndexFragmentFile addUncommittedFile(int linkageID, IIndexFileLocation location, |
| ISignificantMacros macroDictionary) throws CoreException { |
| return getWritableFragment().addUncommittedFile(linkageID, location, macroDictionary); |
| } |
| |
| @Override |
| public IIndexFragmentFile commitUncommittedFile() throws CoreException { |
| return getWritableFragment().commitUncommittedFile(); |
| } |
| |
| @Override |
| public void clearUncommittedFile() throws CoreException { |
| getWritableFragment().clearUncommittedFile(); |
| } |
| |
| @Override |
| public void setFileContent(IIndexFragmentFile file, int linkageID, IncludeInformation[] includes, |
| IASTPreprocessorStatement[] macros, IASTName[][] names, ASTFilePathResolver resolver, |
| YieldableIndexLock lock) throws CoreException, InterruptedException { |
| assert getWritableFragment() == file.getIndexFragment(); |
| |
| for (IncludeInformation include : includes) { |
| if (include.fLocation != null) { |
| include.fTargetFile= addFile(linkageID, include.fLocation, |
| include.fSignificantMacros); |
| } |
| } |
| getWritableFragment().addFileContent(file, includes, macros, names, resolver, lock); |
| } |
| |
| @Override |
| public void clear() throws CoreException { |
| getWritableFragment().clear(); |
| } |
| |
| @Override |
| public void clearFile(IIndexFragmentFile file) throws CoreException { |
| getWritableFragment().clearFile(file); |
| } |
| |
| @Override |
| public void acquireReadLock() throws InterruptedException { |
| checkThread(); |
| assert !fIsWriteLocked: "Read locks are not allowed while write-locked."; //$NON-NLS-1$ |
| super.acquireReadLock(); |
| } |
| |
| @Override |
| public void releaseReadLock() { |
| checkThread(); |
| assert !fIsWriteLocked: "Read locks are not allowed while write-locked."; //$NON-NLS-1$ |
| super.releaseReadLock(); |
| if (getReadLockCount() == 0) |
| fThread= null; |
| } |
| |
| @Override |
| public void acquireWriteLock(IProgressMonitor monitor) throws InterruptedException { |
| checkThread(); |
| assert !fIsWriteLocked: "Multiple write locks is not allowed"; //$NON-NLS-1$ |
| |
| getWritableFragment().acquireWriteLock(getReadLockCount(), monitor); |
| fIsWriteLocked= true; |
| } |
| |
| @Override |
| public void releaseWriteLock() { |
| releaseWriteLock(true); |
| } |
| |
| @Override |
| public void releaseWriteLock(boolean flush) { |
| checkThread(); |
| assert fIsWriteLocked: "No write lock to be released"; //$NON-NLS-1$ |
| |
| // Bug 297641: Result cache of read only providers needs to be cleared. |
| int establishReadlockCount = getReadLockCount(); |
| if (establishReadlockCount == 0) { |
| clearResultCache(); |
| } |
| |
| fIsWriteLocked= false; |
| getWritableFragment().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$ |
| super.clearResultCache(); |
| } |
| |
| @Override |
| public void flush() throws CoreException { |
| assert !fIsWriteLocked; |
| getWritableFragment().flush(); |
| } |
| |
| @Override |
| public long getDatabaseSizeBytes() { |
| return getWritableFragment().getDatabaseSizeBytes(); |
| } |
| |
| @Override |
| public void transferIncluders(IIndexFragmentFile source, IIndexFragmentFile target) throws CoreException { |
| if (source == null || target == null) |
| throw new IllegalArgumentException(); |
| if (source.equals(target)) |
| return; |
| target.transferIncluders(source); |
| } |
| |
| @Override |
| public void transferContext(IIndexFragmentFile source, IIndexFragmentFile target) throws CoreException { |
| if (source == null || target == null) |
| throw new IllegalArgumentException(); |
| if (source.equals(target)) |
| return; |
| target.transferContext(source); |
| } |
| } |