IJ-CR-100779: ReadActionCacheIml decoupled from the ReadMostlyRWLock

GitOrigin-RevId: 6957026b3c35f552d3e01f7608df1f2d4af4784f
This commit is contained in:
Nicolay Mitropolsky
2023-02-21 19:26:52 +00:00
committed by intellij-monorepo-bot
parent 59ea3b7bc5
commit 5aa86e6154
4 changed files with 39 additions and 45 deletions
@@ -57,8 +57,6 @@
<projectService serviceInterface="com.intellij.psi.util.CachedValuesManager"
serviceImplementation="com.intellij.util.CachedValuesManagerImpl"/>
<applicationService serviceInterface="com.intellij.psi.util.ReadActionCache"
serviceImplementation="com.intellij.openapi.application.impl.ReadActionCacheIml"/>
<applicationService serviceInterface="com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry"
serviceImplementation="com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistryImpl"/>
<projectService serviceInterface="com.intellij.psi.util.PsiModificationTracker"
@@ -34,6 +34,7 @@ import com.intellij.openapi.util.*;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.psi.util.ReadActionCache;
import com.intellij.serviceContainer.ComponentManagerImpl;
import com.intellij.ui.ComponentUtil;
import com.intellij.util.*;
@@ -90,6 +91,8 @@ public class ApplicationImpl extends ClientAwareComponentManager implements Appl
private final TransactionGuardImpl myTransactionGuard = new TransactionGuardImpl();
private int myWriteStackBase;
private final ReadActionCacheIml myReadActionCacheIml = new ReadActionCacheIml();
private final long myStartTime = System.currentTimeMillis();
private boolean mySaveAllowed;
private volatile boolean myExitInProgress;
@@ -113,6 +116,7 @@ public class ApplicationImpl extends ClientAwareComponentManager implements Appl
registerServiceInstance(TransactionGuard.class, myTransactionGuard, ComponentManagerImpl.fakeCorePluginDescriptor);
registerServiceInstance(ApplicationInfo.class, ApplicationInfoImpl.getShadowInstance(), ComponentManagerImpl.fakeCorePluginDescriptor);
registerServiceInstance(Application.class, this, ComponentManagerImpl.fakeCorePluginDescriptor);
registerServiceInstance(ReadActionCache.class, myReadActionCacheIml, ComponentManagerImpl.fakeCorePluginDescriptor);
myIsInternal = isInternal;
myTestModeFlag = isTestMode;
@@ -828,6 +832,7 @@ public class ApplicationImpl extends ClientAwareComponentManager implements Appl
action.run();
}
finally {
myReadActionCacheIml.clear();
if (status != null) {
myLock.endRead(status);
}
@@ -841,6 +846,7 @@ public class ApplicationImpl extends ClientAwareComponentManager implements Appl
return computation.compute();
}
finally {
myReadActionCacheIml.clear();
if (status != null) {
myLock.endRead(status);
}
@@ -854,6 +860,7 @@ public class ApplicationImpl extends ClientAwareComponentManager implements Appl
return computation.compute();
}
finally {
myReadActionCacheIml.clear();
if (status != null) {
myLock.endRead(status);
}
@@ -1060,6 +1067,7 @@ public class ApplicationImpl extends ClientAwareComponentManager implements Appl
action.run();
}
finally {
myReadActionCacheIml.clear();
if (status != null) {
myLock.endRead(status);
}
@@ -1233,6 +1241,7 @@ public class ApplicationImpl extends ClientAwareComponentManager implements Appl
@Override
public void finish() {
myReadActionCacheIml.clear();
myLock.endRead(myReader);
}
}
@@ -5,21 +5,41 @@ import com.intellij.openapi.application.ApplicationManager
import com.intellij.psi.util.ReadActionCache
import com.intellij.util.ProcessingContext
class ReadActionCacheIml: ReadActionCache {
private val application: ApplicationImpl?
get() = ApplicationManager.getApplication() as? ApplicationImpl
class ReadActionCacheIml : ReadActionCache {
private val threadProcessingContext: ThreadLocal<ProcessingContext> = ThreadLocal()
override val processingContext: ProcessingContext?
get() = application?.myLock?.processingContext
get() {
threadProcessingContext.get()?.let { return it }
if (ApplicationManager.getApplication().isWriteIntentLockAcquired) return writeActionProcessingContext
if (!ApplicationManager.getApplication().isReadAccessAllowed) return null
threadProcessingContext.set(ProcessingContext())
return threadProcessingContext.get()
}
fun clear() {
threadProcessingContext.remove()
}
private var writeActionProcessingContext: ProcessingContext? = null
override fun <T> allowInWriteAction(supplier: () -> T): T {
val myLock = application?.myLock ?: return supplier.invoke()
return myLock.allowProcessingContextInWriteAction(supplier)
return if (!ApplicationManager.getApplication().isWriteIntentLockAcquired || writeActionProcessingContext != null) {
supplier.invoke()
}
else try {
writeActionProcessingContext = ProcessingContext()
supplier.invoke()
}
finally {
writeActionProcessingContext = null
}
}
override fun allowInWriteAction(runnable: Runnable) {
allowInWriteAction { runnable.run() }
allowInWriteAction { runnable.run() }
}
}
@@ -6,7 +6,6 @@ import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressIndicatorProvider;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.util.ProcessingContext;
import com.intellij.util.containers.ConcurrentList;
import com.intellij.util.containers.ContainerUtil;
import org.intellij.lang.annotations.MagicConstant;
@@ -18,7 +17,6 @@ import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.LockSupport;
import java.util.function.Supplier;
import static com.intellij.openapi.progress.util.ProgressIndicatorUtils.cancelActionsToBeCancelledBeforeWrite;
@@ -72,8 +70,6 @@ final class ReadMostlyRWLock {
thread = readerThread;
}
private ProcessingContext processingContext;
@Override
@NonNls
public String toString() {
@@ -149,10 +145,8 @@ final class ReadMostlyRWLock {
// If implicit read lock is disabled, don't check for write thread, check for true read lock
if (allowImplicitRead)
checkReadThreadAccess();
if (status != null) {
if (status != null)
status.readRequested = false;
status.processingContext = null;
}
if (isWriteRequested()) {
LockSupport.unpark(writeThread); // parked by writeLock()
}
@@ -185,33 +179,6 @@ final class ReadMostlyRWLock {
return R.get().impatientReads;
}
ProcessingContext getProcessingContext() {
if (Thread.currentThread() == writeThread) return writeActionProcessingContext;
Reader reader = R.get();
if (!reader.readRequested) return null;
ProcessingContext context = reader.processingContext;
if (context == null) {
context = reader.processingContext = new ProcessingContext();
}
return context;
}
private ProcessingContext writeActionProcessingContext = null;
<T> T allowProcessingContextInWriteAction(Supplier<T> supplier) {
if (Thread.currentThread() != writeThread || writeActionProcessingContext != null) {
return supplier.get();
}
try {
writeActionProcessingContext = new ProcessingContext();
return supplier.get();
}
finally {
writeActionProcessingContext = null;
}
}
/**
* Executes a {@code runnable} in an "impatient" mode.
* In this mode any attempt to grab read lock