mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-13 15:52:01 +07:00
IJPL-149317 More explicit locks.
GitOrigin-RevId: 95f64ac7da5066d2efb212d4e7cfc2cb98543ac1
This commit is contained in:
committed by
intellij-monorepo-bot
parent
0f67676709
commit
0b6ba6a94d
@@ -11,6 +11,7 @@ import com.intellij.collaboration.ui.util.DimensionRestrictions
|
||||
import com.intellij.collaboration.util.HashingUtil
|
||||
import com.intellij.openapi.application.ModalityState
|
||||
import com.intellij.openapi.application.asContextElement
|
||||
import com.intellij.openapi.application.writeIntentReadAction
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.diagnostic.getOrLogException
|
||||
import com.intellij.openapi.editor.*
|
||||
@@ -85,7 +86,9 @@ private suspend fun <VM : EditorMapped> EditorEx.doRenderInlays(
|
||||
vmsFlow.map {
|
||||
createCustomHashingStrategySet(vmHashingStrategy).apply { addAll(it) }
|
||||
}.collect {
|
||||
positionKeeper.savePosition()
|
||||
writeIntentReadAction {
|
||||
positionKeeper.savePosition()
|
||||
}
|
||||
|
||||
// remove missing
|
||||
val iter = controllersByVmKey.iterator()
|
||||
@@ -105,10 +108,12 @@ private suspend fun <VM : EditorMapped> EditorEx.doRenderInlays(
|
||||
}
|
||||
}
|
||||
|
||||
// immediately validate the editor to recalculate the size with inlays
|
||||
editor.contentComponent.validate()
|
||||
positionKeeper.restorePosition(true)
|
||||
editor.contentComponent.repaint()
|
||||
writeIntentReadAction {
|
||||
// immediately validate the editor to recalculate the size with inlays
|
||||
editor.contentComponent.validate()
|
||||
positionKeeper.restorePosition(true)
|
||||
editor.contentComponent.repaint()
|
||||
}
|
||||
}
|
||||
awaitCancellation()
|
||||
}
|
||||
@@ -128,19 +133,21 @@ private suspend fun <VM : EditorMapped> controlInlay(vm: VM, editor: EditorEx, r
|
||||
combine(lineFlow, visibleFlow, ::Pair)
|
||||
}.distinctUntilChanged()
|
||||
.collect { (line, isVisible) ->
|
||||
val currentInlay = inlay
|
||||
if (line != null && isVisible) {
|
||||
runCatching {
|
||||
val offset = editor.document.getLineEndOffset(line)
|
||||
if (currentInlay == null || !currentInlay.isValid || currentInlay.offset != offset) {
|
||||
currentInlay?.let(Disposer::dispose)
|
||||
inlay = insertComponent(vm, rendererFactory, editor, offset)
|
||||
}
|
||||
}.getOrLogException(LOG)
|
||||
}
|
||||
else if (currentInlay != null) {
|
||||
Disposer.dispose(currentInlay)
|
||||
inlay = null
|
||||
writeIntentReadAction {
|
||||
val currentInlay = inlay
|
||||
if (line != null && isVisible) {
|
||||
runCatching {
|
||||
val offset = editor.document.getLineEndOffset(line)
|
||||
if (currentInlay == null || !currentInlay.isValid || currentInlay.offset != offset) {
|
||||
currentInlay?.let(Disposer::dispose)
|
||||
inlay = insertComponent(vm, rendererFactory, editor, offset)
|
||||
}
|
||||
}.getOrLogException(LOG)
|
||||
}
|
||||
else if (currentInlay != null) {
|
||||
Disposer.dispose(currentInlay)
|
||||
inlay = null
|
||||
}
|
||||
}
|
||||
}
|
||||
awaitCancellation()
|
||||
|
||||
@@ -6244,8 +6244,6 @@ f:com.intellij.util.concurrency.ThreadingAssertions
|
||||
- s:assertReadAccess():V
|
||||
- s:assertWriteAccess():V
|
||||
- s:assertWriteIntentReadAccess():V
|
||||
- s:isImplicitLockOnEDT():Z
|
||||
- s:setImplicitLockOnEDT(Z):V
|
||||
- s:softAssertBackgroundThread():V
|
||||
- s:softAssertEventDispatchThread():V
|
||||
- s:softAssertReadAccess():V
|
||||
|
||||
@@ -32,16 +32,12 @@ public final class ThreadingAssertions {
|
||||
@VisibleForTesting
|
||||
public static final String MUST_EXECUTE_IN_READ_ACTION =
|
||||
"Read access is allowed from inside read-action only (see Application.runReadAction())";
|
||||
private static final String MUST_EXECUTE_IN_READ_ACTION_EXPLICIT =
|
||||
"Read access is allowed from inside explicit read-action only (see Application.runReadAction()). Now implicit WriteIntentReadAction.run() is used.";
|
||||
@Internal
|
||||
@VisibleForTesting
|
||||
public static final String MUST_NOT_EXECUTE_IN_READ_ACTION =
|
||||
"Must not execute inside read action";
|
||||
private static final String MUST_EXECUTE_IN_WRITE_INTENT_READ_ACTION =
|
||||
"Access is allowed from write thread only";
|
||||
private static final String MUST_EXECUTE_IN_WRITE_INTENT_READ_ACTION_EXPLICIT =
|
||||
"Access is allowed from write thread only with explicit WriteIntentReadAction.run(). Now implicit WriteIntentReadAction.run() is used.";
|
||||
@Internal
|
||||
@VisibleForTesting
|
||||
public static final String MUST_EXECUTE_IN_WRITE_ACTION =
|
||||
@@ -57,8 +53,6 @@ public final class ThreadingAssertions {
|
||||
|
||||
private static final String DOCUMENTATION_URL = "https://jb.gg/ij-platform-threading";
|
||||
|
||||
private static boolean implicitLock = false;
|
||||
|
||||
/**
|
||||
* Asserts that the current thread is the event dispatch thread.
|
||||
*
|
||||
@@ -117,17 +111,6 @@ public final class ThreadingAssertions {
|
||||
if (!ApplicationManager.getApplication().isReadAccessAllowed()) {
|
||||
throwThreadAccessException(MUST_EXECUTE_IN_READ_ACTION);
|
||||
}
|
||||
else if (isImplicitLockOnEDT()) {
|
||||
reportImplicitRead();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports message about implicit read to logger at error level
|
||||
*/
|
||||
@Internal
|
||||
public static void reportImplicitRead() {
|
||||
getLogger().error(createThreadAccessException(MUST_EXECUTE_IN_READ_ACTION_EXPLICIT));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -165,17 +148,6 @@ public final class ThreadingAssertions {
|
||||
if (!ApplicationManager.getApplication().isWriteIntentLockAcquired()) {
|
||||
throwWriteIntentReadAccess();
|
||||
}
|
||||
else if (isImplicitLockOnEDT()) {
|
||||
reportImplicitWriteIntent();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports message about implicit read to logger at error level
|
||||
*/
|
||||
@Internal
|
||||
public static void reportImplicitWriteIntent() {
|
||||
getLogger().error(createThreadAccessException(MUST_EXECUTE_IN_WRITE_INTENT_READ_ACTION_EXPLICIT));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -216,16 +188,4 @@ public final class ThreadingAssertions {
|
||||
private static @NotNull String describe(@Nullable Thread o) {
|
||||
return o == null ? "null" : o + " " + System.identityHashCode(o);
|
||||
}
|
||||
|
||||
public static boolean isImplicitLockOnEDT() {
|
||||
if (!EDT.isCurrentThreadEdt())
|
||||
return false;
|
||||
return implicitLock;
|
||||
}
|
||||
|
||||
public static void setImplicitLockOnEDT(boolean implicitLock) {
|
||||
if (!EDT.isCurrentThreadEdt())
|
||||
return;
|
||||
ThreadingAssertions.implicitLock = implicitLock;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -526,7 +526,9 @@ class InlineCompletionHandler(
|
||||
@RequiresEdt
|
||||
private fun traceBlocking(event: InlineCompletionEventType) {
|
||||
ThreadingAssertions.assertEventDispatchThread()
|
||||
eventListeners.getMulticaster().on(event)
|
||||
WriteIntentReadAction.run {
|
||||
eventListeners.getMulticaster().on(event)
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresEdt
|
||||
|
||||
@@ -1041,14 +1041,7 @@ internal fun performActivity(e: AWTEvent, needWIL: Boolean, runnable: () -> Unit
|
||||
else {
|
||||
val runnableWithWIL =
|
||||
if (needWIL) {
|
||||
{
|
||||
ThreadingAssertions.setImplicitLockOnEDT(true)
|
||||
try {
|
||||
WriteIntentReadAction.run(runnable)
|
||||
} finally {
|
||||
ThreadingAssertions.setImplicitLockOnEDT(false)
|
||||
}
|
||||
}
|
||||
{ WriteIntentReadAction.run(runnable) }
|
||||
}
|
||||
else {
|
||||
runnable
|
||||
|
||||
@@ -81,13 +81,10 @@ internal object AnyThreadWriteThreadingSupport: ThreadingSupport {
|
||||
is WriteIntentPermit, is WritePermit -> release = false
|
||||
}
|
||||
|
||||
val prevImplicitLock = ThreadingAssertions.isImplicitLockOnEDT()
|
||||
try {
|
||||
ThreadingAssertions.setImplicitLockOnEDT(false)
|
||||
return computation.compute()
|
||||
}
|
||||
finally {
|
||||
ThreadingAssertions.setImplicitLockOnEDT(prevImplicitLock)
|
||||
if (release) {
|
||||
ts.release()
|
||||
}
|
||||
@@ -109,21 +106,10 @@ internal object AnyThreadWriteThreadingSupport: ThreadingSupport {
|
||||
|
||||
override fun isWriteIntentLocked(): Boolean {
|
||||
val ts = myState.get()
|
||||
// check for implicit
|
||||
if (ts.hasWriteIntent && ThreadingAssertions.isImplicitLockOnEDT()) {
|
||||
ThreadingAssertions.reportImplicitWriteIntent()
|
||||
}
|
||||
return ts.hasWrite || ts.hasWriteIntent
|
||||
}
|
||||
|
||||
override fun isReadAccessAllowed(): Boolean {
|
||||
val ts = myState.get()
|
||||
// check for implicit
|
||||
if (ts.hasWriteIntent && ThreadingAssertions.isImplicitLockOnEDT()) {
|
||||
ThreadingAssertions.reportImplicitRead()
|
||||
}
|
||||
return ts.hasPermit
|
||||
}
|
||||
override fun isReadAccessAllowed(): Boolean = myState.get().hasPermit
|
||||
|
||||
override fun executeOnPooledThread(action: Runnable, expired: BooleanSupplier): Future<*> {
|
||||
val actionDecorated = decorateRunnable(action)
|
||||
@@ -235,17 +221,10 @@ internal object AnyThreadWriteThreadingSupport: ThreadingSupport {
|
||||
fireBeforeReadActionStart(clazz)
|
||||
val ts = myState.get()
|
||||
if (ts.hasPermit) {
|
||||
val prevImplicitLock = ThreadingAssertions.isImplicitLockOnEDT()
|
||||
ThreadingAssertions.setImplicitLockOnEDT(false)
|
||||
try {
|
||||
fireReadActionStarted(clazz)
|
||||
val rv = block.compute()
|
||||
fireReadActionFinished(clazz)
|
||||
return rv
|
||||
}
|
||||
finally {
|
||||
ThreadingAssertions.setImplicitLockOnEDT(prevImplicitLock)
|
||||
}
|
||||
fireReadActionStarted(clazz)
|
||||
val rv = block.compute()
|
||||
fireReadActionFinished(clazz)
|
||||
return rv
|
||||
}
|
||||
else {
|
||||
ts.permit = tryGetReadPermit()
|
||||
@@ -277,8 +256,6 @@ internal object AnyThreadWriteThreadingSupport: ThreadingSupport {
|
||||
} while (ts.permit == null)
|
||||
}
|
||||
}
|
||||
val prevImplicitLock = ThreadingAssertions.isImplicitLockOnEDT()
|
||||
ThreadingAssertions.setImplicitLockOnEDT(false)
|
||||
try {
|
||||
fireReadActionStarted(clazz)
|
||||
val rv = block.compute()
|
||||
@@ -286,7 +263,6 @@ internal object AnyThreadWriteThreadingSupport: ThreadingSupport {
|
||||
return rv
|
||||
}
|
||||
finally {
|
||||
ThreadingAssertions.setImplicitLockOnEDT(prevImplicitLock)
|
||||
ts.release()
|
||||
fireAfterReadActionFinished(clazz)
|
||||
}
|
||||
@@ -296,16 +272,9 @@ internal object AnyThreadWriteThreadingSupport: ThreadingSupport {
|
||||
override fun tryRunReadAction(action: Runnable): Boolean {
|
||||
val ts = myState.get()
|
||||
if (ts.hasPermit) {
|
||||
val prevImplicitLock = ThreadingAssertions.isImplicitLockOnEDT()
|
||||
ThreadingAssertions.setImplicitLockOnEDT(false)
|
||||
try {
|
||||
fireReadActionStarted(action.javaClass)
|
||||
action.run()
|
||||
fireReadActionFinished(action.javaClass)
|
||||
}
|
||||
finally {
|
||||
ThreadingAssertions.setImplicitLockOnEDT(prevImplicitLock)
|
||||
}
|
||||
fireReadActionStarted(action.javaClass)
|
||||
action.run()
|
||||
fireReadActionFinished(action.javaClass)
|
||||
return true
|
||||
}
|
||||
else {
|
||||
@@ -314,8 +283,6 @@ internal object AnyThreadWriteThreadingSupport: ThreadingSupport {
|
||||
if (!ts.hasPermit) {
|
||||
return false
|
||||
}
|
||||
val prevImplicitLock = ThreadingAssertions.isImplicitLockOnEDT()
|
||||
ThreadingAssertions.setImplicitLockOnEDT(false)
|
||||
try {
|
||||
fireReadActionStarted(action.javaClass)
|
||||
action.run()
|
||||
@@ -323,7 +290,6 @@ internal object AnyThreadWriteThreadingSupport: ThreadingSupport {
|
||||
return true
|
||||
}
|
||||
finally {
|
||||
ThreadingAssertions.setImplicitLockOnEDT(prevImplicitLock)
|
||||
ts.release()
|
||||
fireAfterReadActionFinished(action.javaClass)
|
||||
}
|
||||
|
||||
@@ -3733,7 +3733,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
mouseSelectionStateAlarm.cancel();
|
||||
if (myMouseSelectionState != MOUSE_SELECTION_STATE_NONE) {
|
||||
if (mouseSelectionStateResetRunnable == null) {
|
||||
mouseSelectionStateResetRunnable = () -> resetMouseSelectionState(null, null);
|
||||
mouseSelectionStateResetRunnable = () -> WriteIntentReadAction.run((Runnable)() -> resetMouseSelectionState(null, null));
|
||||
}
|
||||
mouseSelectionStateAlarm.request(Registry.intValue("editor.mouseSelectionStateResetTimeout"),
|
||||
ModalityState.stateForComponent(myEditorComponent),
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
package com.intellij.testFramework.junit5.showcase
|
||||
|
||||
import com.intellij.openapi.application.EDT
|
||||
import com.intellij.openapi.application.writeIntentReadAction
|
||||
import com.intellij.testFramework.junit5.TestApplication
|
||||
import com.intellij.testFramework.junit5.fixture.*
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -32,8 +33,10 @@ class JUnit5EditorFixtureTest {
|
||||
fun `caret position in editors`() {
|
||||
runBlocking {
|
||||
withContext(Dispatchers.EDT) {
|
||||
localEditor.get().caretModel.moveToOffset(2)
|
||||
Assertions.assertEquals(2, localEditor.get().caretModel.offset)
|
||||
writeIntentReadAction {
|
||||
localEditor.get().caretModel.moveToOffset(2)
|
||||
Assertions.assertEquals(2, localEditor.get().caretModel.offset)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -42,8 +45,10 @@ class JUnit5EditorFixtureTest {
|
||||
fun `selection in editors`() {
|
||||
runBlocking {
|
||||
withContext(Dispatchers.EDT) {
|
||||
localEditor.get().selectionModel.setSelection(1, 3)
|
||||
Assertions.assertEquals("bc", localEditor.get().selectionModel.selectedText)
|
||||
writeIntentReadAction {
|
||||
localEditor.get().selectionModel.setSelection(1, 3)
|
||||
Assertions.assertEquals("bc", localEditor.get().selectionModel.selectedText)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,7 +85,9 @@ class InlineCompletionLifecycleTestDSL(val fixture: CodeInsightTestFixture) {
|
||||
withContext(Dispatchers.EDT) {
|
||||
val lookup = fixture.lookup as? LookupImpl
|
||||
assertThat(lookup).isNotNull()
|
||||
lookup!!.hideLookup(false)
|
||||
writeIntentReadAction {
|
||||
lookup!!.hideLookup(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.intellij.coverage.CoverageIntegrationBaseTest
|
||||
import com.intellij.openapi.application.EDT
|
||||
import com.intellij.openapi.application.readAction
|
||||
import com.intellij.openapi.application.writeAction
|
||||
import com.intellij.openapi.application.writeIntentReadAction
|
||||
import com.intellij.openapi.editor.colors.CodeInsightColors
|
||||
import com.intellij.openapi.editor.impl.EditorImpl
|
||||
import com.intellij.openapi.editor.markup.FillingLineMarkerRenderer
|
||||
@@ -187,7 +188,9 @@ internal suspend fun findEditor(project: Project, className: String): EditorImpl
|
||||
internal suspend fun closeEditor(project: Project, className: String) {
|
||||
val psiClass = getPsiClass(project, className)
|
||||
withContext(Dispatchers.EDT) {
|
||||
FileEditorManager.getInstance(project).closeFile(psiClass.containingFile.virtualFile)
|
||||
writeIntentReadAction {
|
||||
FileEditorManager.getInstance(project).closeFile(psiClass.containingFile.virtualFile)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -90,21 +90,23 @@ abstract class AbstractGradleMultiFileQuickFixTest : MultiplePluginVersionGradle
|
||||
refreshRecursively(projectVFile)
|
||||
|
||||
withContext(Dispatchers.EDT) {
|
||||
PlatformTestUtil.assertDirectoriesEqual(
|
||||
expected,
|
||||
projectVFile,
|
||||
fun(vFile: VirtualFile): Boolean {
|
||||
if (vFile.parent == projectVFile) {
|
||||
when (vFile.name) {
|
||||
".gradle", "gradle", "build", "gradle.properties", "gradlew", "gradlew.bat", ".kotlin" -> return false
|
||||
writeIntentReadAction {
|
||||
PlatformTestUtil.assertDirectoriesEqual(
|
||||
expected,
|
||||
projectVFile,
|
||||
fun(vFile: VirtualFile): Boolean {
|
||||
if (vFile.parent == projectVFile) {
|
||||
when (vFile.name) {
|
||||
".gradle", "gradle", "build", "gradle.properties", "gradlew", "gradlew.bat", ".kotlin" -> return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ignoreChangesInBuildScriptFiles && ".gradle" in vFile.name) return false
|
||||
if (ignoreChangesInBuildScriptFiles && ".gradle" in vFile.name) return false
|
||||
|
||||
return additionalResultFileFilter(vFile)
|
||||
},
|
||||
)
|
||||
return additionalResultFileFilter(vFile)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.intellij.pycharm.community.ide.impl.newProject.impl.emptyProject
|
||||
|
||||
import com.intellij.openapi.application.EDT
|
||||
import com.intellij.openapi.application.writeAction
|
||||
import com.intellij.openapi.application.writeIntentReadAction
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.projectRoots.Sdk
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
@@ -19,7 +20,9 @@ class PyV3EmptyProjectSettings(var generateWelcomeScript: Boolean = false) : PyV
|
||||
PyWelcome.prepareFile(module.project, baseDir)
|
||||
}
|
||||
withContext(Dispatchers.EDT) {
|
||||
file.navigate(true)
|
||||
writeIntentReadAction {
|
||||
file.navigate(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user