[threading] IJPL-148438: Extract implementation for locks to a separate module

GitOrigin-RevId: 4f501adff06ed8c9de63b85c652b888df4487e11
This commit is contained in:
Konstantin Nisht
2025-06-11 17:41:52 +02:00
committed by intellij-monorepo-bot
parent 1bd253cf76
commit 03dce4a756
26 changed files with 116 additions and 56 deletions

1
.idea/modules.xml generated
View File

@@ -861,6 +861,7 @@
<module fileurl="file://$PROJECT_DIR$/platform/lang-impl/intellij.platform.lang.tests.iml" filepath="$PROJECT_DIR$/platform/lang-impl/intellij.platform.lang.tests.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/IntelliLang/intellij.platform.langInjection.iml" filepath="$PROJECT_DIR$/plugins/IntelliLang/intellij.platform.langInjection.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/IntelliLang/IntelliLang-tests/intellij.platform.langInjection.tests.iml" filepath="$PROJECT_DIR$/plugins/IntelliLang/IntelliLang-tests/intellij.platform.langInjection.tests.iml" />
<module fileurl="file://$PROJECT_DIR$/platform/locking.impl/intellij.platform.locking.impl.iml" filepath="$PROJECT_DIR$/platform/locking.impl/intellij.platform.locking.impl.iml" />
<module fileurl="file://$PROJECT_DIR$/platform/lvcs-api/intellij.platform.lvcs.iml" filepath="$PROJECT_DIR$/platform/lvcs-api/intellij.platform.lvcs.iml" />
<module fileurl="file://$PROJECT_DIR$/platform/lvcs-impl/intellij.platform.lvcs.impl.iml" filepath="$PROJECT_DIR$/platform/lvcs-impl/intellij.platform.lvcs.impl.iml" />
<module fileurl="file://$PROJECT_DIR$/platform/macro/intellij.platform.macro.iml" filepath="$PROJECT_DIR$/platform/macro/intellij.platform.macro.iml" />

View File

@@ -0,0 +1,20 @@
### auto-generated section `build intellij.platform.locking.impl` start
load("@rules_jvm//:jvm.bzl", "jvm_library")
jvm_library(
name = "locking.impl",
module_name = "intellij.platform.locking.impl",
visibility = ["//visibility:public"],
srcs = glob(["src/**/*.kt", "src/**/*.java"], allow_empty = True),
deps = [
"@lib//:kotlin-stdlib",
"@lib//:kotlinx-coroutines-core",
"@lib//:jetbrains-annotations",
"//platform/util-rt",
"//platform/util",
"//platform/util/coroutines",
"@lib//:jetbrains-intellij-deps-rwmutex-idea",
"//platform/core-api:core",
]
)
### auto-generated section `build intellij.platform.locking.impl` end

View File

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" packagePrefix="com.intellij.platform.locking.impl" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="kotlin-stdlib" level="project" />
<orderEntry type="library" name="kotlinx-coroutines-core" level="project" />
<orderEntry type="library" name="jetbrains-annotations" level="project" />
<orderEntry type="module" module-name="intellij.platform.util.rt" />
<orderEntry type="module" module-name="intellij.platform.util" />
<orderEntry type="module" module-name="intellij.platform.util.coroutines" />
<orderEntry type="library" name="jetbrains.intellij.deps.rwmutex.idea" level="project" />
<orderEntry type="module" module-name="intellij.platform.core" />
</component>
</module>

View File

@@ -1,5 +1,5 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.openapi.application.impl
package com.intellij.platform.locking.impl
import com.intellij.concurrency.currentThreadContext
import com.intellij.concurrency.installThreadContext
@@ -10,7 +10,6 @@ import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.progress.Cancellation
import com.intellij.openapi.util.text.StringUtil
import com.intellij.util.ReflectionUtil
import com.jetbrains.rd.util.forEachReversed
import kotlinx.coroutines.*
import kotlinx.coroutines.internal.intellij.IntellijCoroutines
import org.jetbrains.annotations.ApiStatus
@@ -82,10 +81,6 @@ private data class ExposedWritePermitData(
val oldPermit: WriteIntentPermit?,
)
@ApiStatus.Internal
fun newLockingSupport(): ThreadingSupport =
NestedLocksThreadingSupport()
/**
* This class implements a technique that we call "nested locks" (a.k.a. "n-locks", where "n" stands for "natural number").
*
@@ -155,8 +150,6 @@ internal class NestedLocksThreadingSupport : ThreadingSupport {
companion object {
private const val SPIN_TO_WAIT_FOR_LOCK: Int = 100
private val logger = Logger.getInstance(NestedLocksThreadingSupport::class.java)
val defaultInstance: NestedLocksThreadingSupport = NestedLocksThreadingSupport()
}
/**
@@ -336,8 +329,9 @@ internal class NestedLocksThreadingSupport : ThreadingSupport {
hack_setPublishedPermitData(null)
val writePermits = currentPublishedPermits.writePermitStack
// forEachReversed is the most performant loop in kotlin, it uses indexes instead of iterators
writePermits.forEachReversed {
it.release()
var writePermitIndex = writePermits.lastIndex
while (writePermitIndex >= 0) {
writePermits[writePermitIndex--].release()
}
currentPublishedPermits.finalWritePermit.release()
if (currentPublishedPermits.oldPermit == null) {
@@ -1037,8 +1031,9 @@ internal class NestedLocksThreadingSupport : ThreadingSupport {
"Suspending write action was requested, but the thread did not start write action properly"
}
hack_setPublishedPermitData(null)
exposedPermitData.writePermitStack.forEachReversed {
it.release()
var writePermitIndex = exposedPermitData.writePermitStack.lastIndex
while (writePermitIndex >= 0) {
exposedPermitData.writePermitStack[writePermitIndex--].release()
}
val rootWriteIntentPermit = exposedPermitData.originalWriteIntentPermit
permit.writePermit.release()
@@ -1155,7 +1150,7 @@ internal class NestedLocksThreadingSupport : ThreadingSupport {
}
}
override fun allowTakingLocksInsideAndRun(action: java.lang.Runnable) {
override fun allowTakingLocksInsideAndRun(action: Runnable) {
val currentValue = myLockingProhibited.get()
myLockingProhibited.set(null)
try {

View File

@@ -0,0 +1,18 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
@file:JvmName("IntelliJLockingUtil")
package com.intellij.platform.locking.impl
import com.intellij.openapi.application.ThreadingSupport
import org.jetbrains.annotations.ApiStatus
private val instance = NestedLocksThreadingSupport()
@ApiStatus.Internal
fun newLockingSupport(): ThreadingSupport =
NestedLocksThreadingSupport()
@ApiStatus.Internal
fun getGlobalThreadingSupport(): ThreadingSupport {
return instance
}

View File

@@ -122,7 +122,6 @@ jvm_library(
"//platform/settings",
"//platform/util/coroutines",
"@lib//:jetbrains-annotations",
"@lib//:jetbrains-intellij-deps-rwmutex-idea",
"@lib//:lz4-java",
"//platform/ml-api:ml",
"@lib//:kotlinx-collections-immutable",
@@ -145,6 +144,7 @@ jvm_library(
"//platform/plugins/parser/impl",
"//platform/eel",
"//platform/platform-util-io:ide-util-io",
"//platform/locking.impl",
],
exports = [
"//platform/platform-api:ide",
@@ -279,7 +279,6 @@ jvm_library(
"//platform/settings",
"//platform/util/coroutines",
"@lib//:jetbrains-annotations",
"@lib//:jetbrains-intellij-deps-rwmutex-idea",
"@lib//:lz4-java",
"//platform/ml-api:ml",
"@lib//:kotlinx-collections-immutable",
@@ -302,6 +301,7 @@ jvm_library(
"//platform/plugins/parser/impl",
"//platform/eel",
"//platform/platform-util-io:ide-util-io",
"//platform/locking.impl",
],
runtime_deps = [":ide-impl_resources"]
)

View File

@@ -133,7 +133,6 @@
<orderEntry type="module" module-name="intellij.platform.settings" />
<orderEntry type="module" module-name="intellij.platform.util.coroutines" />
<orderEntry type="library" name="jetbrains-annotations" level="project" />
<orderEntry type="library" name="jetbrains.intellij.deps.rwmutex.idea" level="project" />
<orderEntry type="library" name="lz4-java" level="project" />
<orderEntry type="module" module-name="intellij.platform.ml" />
<orderEntry type="library" name="kotlinx-collections-immutable" level="project" />
@@ -164,5 +163,6 @@
<orderEntry type="module" module-name="intellij.platform.syntax.extensions" scope="RUNTIME" />
<orderEntry type="module" module-name="intellij.platform.eel" />
<orderEntry type="module" module-name="intellij.platform.ide.util.io" />
<orderEntry type="module" module-name="intellij.platform.locking.impl" />
</component>
</module>

View File

@@ -18,7 +18,6 @@ import com.intellij.openapi.Disposable
import com.intellij.openapi.application.*
import com.intellij.openapi.application.ex.ApplicationManagerEx
import com.intellij.openapi.application.impl.InvocationUtil
import com.intellij.openapi.application.impl.getGlobalThreadingSupport
import com.intellij.openapi.components.serviceIfCreated
import com.intellij.openapi.diagnostic.ControlFlowException
import com.intellij.openapi.diagnostic.Logger
@@ -42,6 +41,7 @@ import com.intellij.openapi.wm.WindowManager
import com.intellij.openapi.wm.ex.WindowManagerEx
import com.intellij.openapi.wm.impl.FocusManagerImpl
import com.intellij.platform.ide.bootstrap.StartupErrorReporter
import com.intellij.platform.locking.impl.getGlobalThreadingSupport
import com.intellij.ui.ComponentUtil
import com.intellij.ui.awt.RelativePoint
import com.intellij.ui.speedSearch.SpeedSearchSupply

View File

@@ -6,11 +6,11 @@ import com.intellij.ide.ui.ShowingContainer
import com.intellij.idea.AppMode
import com.intellij.openapi.application.AccessToken
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.impl.getGlobalThreadingSupport
import com.intellij.openapi.client.ClientKind
import com.intellij.openapi.client.ClientSessionsManager
import com.intellij.openapi.diagnostic.debug
import com.intellij.openapi.diagnostic.logger
import com.intellij.platform.locking.impl.getGlobalThreadingSupport
import java.awt.*
import java.awt.event.FocusEvent
import java.awt.event.HierarchyEvent

View File

@@ -24,7 +24,6 @@ import com.intellij.openapi.actionSystem.impl.ActionMenu.Companion.isAlignedInGr
import com.intellij.openapi.actionSystem.util.ActionSystem
import com.intellij.openapi.application.*
import com.intellij.openapi.application.ex.ApplicationManagerEx
import com.intellij.openapi.application.impl.getGlobalThreadingSupport
import com.intellij.openapi.components.service
import com.intellij.openapi.diagnostic.logger
import com.intellij.openapi.editor.ex.EditorGutterComponentEx
@@ -44,6 +43,7 @@ import com.intellij.platform.ide.menu.FrameMenuUiKind
import com.intellij.platform.ide.menu.IdeJMenuBar
import com.intellij.platform.ide.menu.MacNativeActionMenuItem
import com.intellij.platform.ide.menu.createMacNativeActionMenu
import com.intellij.platform.locking.impl.getGlobalThreadingSupport
import com.intellij.ui.AnimatedIcon
import com.intellij.ui.ClientProperty
import com.intellij.ui.ExperimentalUI

View File

@@ -44,6 +44,7 @@ import com.intellij.platform.diagnostic.telemetry.IJTracer;
import com.intellij.platform.diagnostic.telemetry.PlatformScopesKt;
import com.intellij.platform.diagnostic.telemetry.TelemetryManager;
import com.intellij.platform.diagnostic.telemetry.helpers.TraceKt;
import com.intellij.platform.locking.impl.IntelliJLockingUtil;
import com.intellij.psi.util.ReadActionCache;
import com.intellij.ui.ComponentUtil;
import com.intellij.util.*;
@@ -1011,7 +1012,7 @@ public final class ApplicationImpl extends ClientAwareComponentManager implement
@Nls(capitalization = Nls.Capitalization.Title) @Nullable String cancelText,
@NotNull Consumer<? super @Nullable ProgressIndicator> action
) {
return getThreadingSupport().runWriteAction(action.getClass(), () -> {
return IntelliJLockingUtil.getGlobalThreadingSupport().runWriteAction(action.getClass(), () -> {
var indicator = new PotemkinProgress(title, project, parentComponent, cancelText);
indicator.runInSwingThread(() -> {
action.accept(indicator);
@@ -1364,16 +1365,16 @@ public final class ApplicationImpl extends ClientAwareComponentManager implement
return true;
}, app.getCoroutineScope());
getThreadingSupport().setReadActionListener(app.myLockDispatcherListener);
getThreadingSupport().setWriteActionListener(app.myLockDispatcherListener);
getThreadingSupport().setWriteIntentReadActionListener(app.myLockDispatcherListener);
getThreadingSupport().setLockAcquisitionListener(app.myLockDispatcherListener);
getThreadingSupport().setWriteLockReacquisitionListener(app.myLockDispatcherListener);
getThreadingSupport().setLegacyIndicatorProvider(myLegacyIndicatorProvider);
app.getThreadingSupport().setReadActionListener(app.myLockDispatcherListener);
app.getThreadingSupport().setWriteActionListener(app.myLockDispatcherListener);
app.getThreadingSupport().setWriteIntentReadActionListener(app.myLockDispatcherListener);
app.getThreadingSupport().setLockAcquisitionListener(app.myLockDispatcherListener);
app.getThreadingSupport().setWriteLockReacquisitionListener(app.myLockDispatcherListener);
app.getThreadingSupport().setLegacyIndicatorProvider(myLegacyIndicatorProvider);
if (ThreadingRuntimeFlagsKt.getInstallSuvorovProgress()) {
SwingUtilities.invokeLater(() -> {
SuvorovProgress.INSTANCE.init(app);
getThreadingSupport().setLockAcquisitionInterceptor((deferred) -> {
app.getThreadingSupport().setLockAcquisitionInterceptor((deferred) -> {
SuvorovProgress.dispatchEventsUntilComputationCompletes(deferred);
return Unit.INSTANCE;
});
@@ -1611,8 +1612,8 @@ public final class ApplicationImpl extends ClientAwareComponentManager implement
return getThreadingSupport().isParallelizedReadAction(context);
}
private static @NotNull ThreadingSupport getThreadingSupport() {
return AppImplKt.getGlobalThreadingSupport();
public @NotNull ThreadingSupport getThreadingSupport() {
return IntelliJLockingUtil.getGlobalThreadingSupport();
}
@RequiresBackgroundThread(generateAssertion = false)

View File

@@ -28,6 +28,7 @@ import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.platform.diagnostic.telemetry.TelemetryManager;
import com.intellij.platform.locking.impl.IntelliJLockingUtil;
import com.intellij.psi.PsiElement;
import com.intellij.util.ArrayUtil;
import com.intellij.util.RunnableCallable;
@@ -137,7 +138,7 @@ public final class NonBlockingReadActionImpl<T> implements NonBlockingReadAction
private static void invokeLater(@NotNull Runnable runnable) {
Application app = ApplicationManager.getApplication();
AppImplKt.getGlobalThreadingSupport().runWhenWriteActionIsCompleted(() -> {
IntelliJLockingUtil.getGlobalThreadingSupport().runWhenWriteActionIsCompleted(() -> {
SideEffectGuard.computeWithAllowedSideEffectsBlocking(EnumSet.of(SideEffectGuard.EffectType.INVOKE_LATER), () -> {
app.invokeLaterOnWriteThread(runnable, ModalityState.any(), app.getDisposed());
return Unit.INSTANCE;

View File

@@ -2,20 +2,14 @@
package com.intellij.openapi.application.impl
import com.intellij.concurrency.ContextAwareRunnable
import com.intellij.core.rwmutex.ReadPermit
import com.intellij.openapi.application.ThreadingSupport
import com.intellij.openapi.application.readLockCompensationTimeout
import com.intellij.openapi.progress.ProcessCanceledException
import com.intellij.openapi.util.ThrowableComputable
import com.intellij.openapi.util.coroutines.runSuspend
import com.intellij.util.ThrowableRunnable
import io.opentelemetry.api.metrics.BatchCallback
import io.opentelemetry.api.metrics.Meter
import kotlinx.coroutines.InternalCoroutinesApi
import kotlinx.coroutines.internal.intellij.IntellijCoroutines
import org.jetbrains.annotations.ApiStatus
import org.jetbrains.annotations.TestOnly
import org.jetbrains.annotations.VisibleForTesting
import java.util.concurrent.atomic.AtomicInteger
import java.util.concurrent.atomic.AtomicReference
import kotlin.time.Duration
@@ -90,11 +84,6 @@ internal fun rethrowExceptions(transformer: (Runnable) -> Runnable, actual: Runn
}
}
@ApiStatus.Internal
fun getGlobalThreadingSupport(): ThreadingSupport {
return NestedLocksThreadingSupport.defaultInstance
}
@Volatile
private var compensationTimeout: Duration? = if (readLockCompensationTimeout == -1) {
null

View File

@@ -7,7 +7,7 @@ import com.intellij.openapi.application.ReadAction
import com.intellij.openapi.application.ReadAction.CannotReadException
import com.intellij.openapi.application.ReadConstraint
import com.intellij.openapi.application.ex.ApplicationEx
import com.intellij.openapi.application.impl.getGlobalThreadingSupport
import com.intellij.platform.locking.impl.getGlobalThreadingSupport
import kotlinx.coroutines.*
import kotlin.coroutines.coroutineContext
import kotlin.coroutines.resume

View File

@@ -5,11 +5,11 @@ import com.intellij.CommonBundle
import com.intellij.diagnostic.LoadingState
import com.intellij.ide.IdeEventQueue
import com.intellij.openapi.Disposable
import com.intellij.openapi.application.impl.getGlobalThreadingSupport
import com.intellij.openapi.diagnostic.thisLogger
import com.intellij.openapi.progress.impl.fus.FreezeUiUsageCollector
import com.intellij.openapi.util.Disposer
import com.intellij.openapi.util.registry.Registry
import com.intellij.platform.locking.impl.getGlobalThreadingSupport
import com.intellij.util.ui.AsyncProcessIcon
import kotlinx.coroutines.Deferred
import kotlinx.coroutines.InternalCoroutinesApi

View File

@@ -13,7 +13,6 @@ import com.intellij.openapi.application.AccessToken;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.WriteIntentReadAction;
import com.intellij.openapi.application.impl.AppImplKt;
import com.intellij.openapi.application.impl.LaterInvocator;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.command.CommandProcessorEx;
@@ -40,6 +39,7 @@ import com.intellij.openapi.wm.impl.ProjectFrameHelper;
import com.intellij.openapi.wm.impl.customFrameDecorations.header.CustomFrameDialogContent;
import com.intellij.openapi.wm.impl.customFrameDecorations.header.CustomHeader;
import com.intellij.platform.ide.bootstrap.SplashManagerKt;
import com.intellij.platform.locking.impl.IntelliJLockingUtil;
import com.intellij.reference.SoftReference;
import com.intellij.ui.*;
import com.intellij.ui.components.JBLayeredPane;
@@ -440,7 +440,7 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer {
var pair = ApplicationManager.getApplication().isWriteAccessAllowed()
? new Pair<>(EmptyCoroutineContext.INSTANCE, AccessToken.EMPTY_ACCESS_TOKEN)
: AppImplKt.getGlobalThreadingSupport().getPermitAsContextElement(ThreadContext.currentThreadContext(), true);
: IntelliJLockingUtil.getGlobalThreadingSupport().getPermitAsContextElement(ThreadContext.currentThreadContext(), true);
lockContextCleanup = ThreadContext.installThreadContext(pair.getFirst(), true);
lockCleanup = pair.getSecond();
}

View File

@@ -6,8 +6,9 @@ import com.intellij.ide.impl.ProjectUtil;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.PlatformCoreDataKeys;
import com.intellij.openapi.application.*;
import com.intellij.openapi.application.impl.AppImplKt;
import com.intellij.openapi.application.ApplicationActivationListener;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.JBPopup;
@@ -17,6 +18,7 @@ import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.openapi.wm.IdeFrame;
import com.intellij.openapi.wm.ex.IdeFocusTraversalPolicy;
import com.intellij.platform.locking.impl.IntelliJLockingUtil;
import com.intellij.ui.ComponentUtil;
import com.intellij.ui.DirtyUI;
import com.intellij.ui.popup.AbstractPopup;
@@ -173,7 +175,7 @@ public final class FocusManagerImpl extends IdeFocusManager implements Disposabl
boolean expired = runnable instanceof ExpirableRunnable && ((ExpirableRunnable)runnable).isExpired();
if (!expired) {
// Even immediate code need explicit write-safe context, not implicit one
AppImplKt.getGlobalThreadingSupport().runPreventiveWriteIntentReadAction(() -> {
IntelliJLockingUtil.getGlobalThreadingSupport().runPreventiveWriteIntentReadAction(() -> {
runnable.run();
return null;
});

View File

@@ -162,6 +162,7 @@ jvm_library(
"//platform/syntax/syntax-psi-tests:psi-tests_test_lib",
"//xml/xml-psi-api:psi",
"//platform/runtime/product",
"//platform/locking.impl",
],
runtime_deps = [
":tests_test_resources",

View File

@@ -143,5 +143,6 @@
<orderEntry type="module" module-name="intellij.platform.syntax.psi.tests" scope="TEST" />
<orderEntry type="module" module-name="intellij.xml.psi" scope="TEST" />
<orderEntry type="module" module-name="intellij.platform.runtime.product" scope="TEST" />
<orderEntry type="module" module-name="intellij.platform.locking.impl" scope="TEST" />
</component>
</module>

View File

@@ -9,6 +9,7 @@ import com.intellij.openapi.progress.runBlockingCancellable
import com.intellij.openapi.progress.util.ProgressIndicatorUtils
import com.intellij.platform.ide.progress.ModalTaskOwner
import com.intellij.platform.ide.progress.runWithModalProgressBlocking
import com.intellij.platform.locking.impl.getGlobalThreadingSupport
import com.intellij.testFramework.common.timeoutRunBlocking
import com.intellij.testFramework.junit5.TestApplication
import com.intellij.util.application

View File

@@ -11,6 +11,7 @@ import com.intellij.openapi.progress.Cancellation
import com.intellij.openapi.progress.ProcessCanceledException
import com.intellij.openapi.progress.ProgressManager
import com.intellij.openapi.project.DumbAware
import com.intellij.platform.locking.impl.getGlobalThreadingSupport
import com.intellij.testFramework.common.timeoutRunBlocking
import com.intellij.testFramework.junit5.TestApplication
import com.intellij.util.application

View File

@@ -2,11 +2,15 @@
package com.intellij.openapi.application.impl
import com.intellij.openapi.application.*
import com.intellij.openapi.application.ApplicationListener
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.EDT
import com.intellij.openapi.application.readAction
import com.intellij.openapi.progress.runBlockingCancellable
import com.intellij.openapi.util.Disposer
import com.intellij.platform.ide.progress.ModalTaskOwner
import com.intellij.platform.ide.progress.runWithModalProgressBlocking
import com.intellij.platform.locking.impl.getGlobalThreadingSupport
import com.intellij.testFramework.common.timeoutRunBlocking
import com.intellij.testFramework.junit5.TestApplication
import com.intellij.util.concurrency.Semaphore
@@ -16,7 +20,6 @@ import kotlinx.coroutines.joinAll
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.Assumptions
import org.junit.jupiter.api.RepeatedTest
import kotlin.test.assertFalse

View File

@@ -5,7 +5,7 @@ import com.intellij.concurrency.currentThreadOverriddenContextOrNull
import com.intellij.openapi.application.ReadAction
import com.intellij.openapi.application.edtWriteAction
import com.intellij.openapi.application.impl.ModalityStateEx
import com.intellij.openapi.application.impl.getGlobalThreadingSupport
import com.intellij.platform.locking.impl.getGlobalThreadingSupport
import com.intellij.testFramework.assertErrorLogged
import com.intellij.testFramework.common.timeoutRunBlocking
import com.intellij.testFramework.junit5.RegistryKey

View File

@@ -5,7 +5,7 @@ import com.intellij.diagnostic.ThreadDumper
import com.intellij.openapi.Disposable
import com.intellij.openapi.application.ApplicationListener
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.impl.getGlobalThreadingSupport
import com.intellij.openapi.application.impl.ApplicationImpl
import com.intellij.openapi.diagnostic.thisLogger
import com.intellij.openapi.progress.runBlockingMaybeCancellable
import com.intellij.openapi.project.*
@@ -94,12 +94,19 @@ private class IndexWaiter(private val project: Project) {
thisLogger().debug("waitNow will be waiting, thread=${Thread.currentThread()}")
}
if (ApplicationManager.getApplication().isDispatchThread) {
val application = ApplicationManager.getApplication()
if (application.isDispatchThread) {
do {
val threadingSupport = getGlobalThreadingSupport()
threadingSupport.releaseTheAcquiredWriteIntentLockThenExecuteActionAndTakeWriteIntentLockBack {
val runnable = {
PlatformTestUtil.waitWithEventsDispatching("Indexing timeout", { !shouldWait() }, 600)
}
if (application is ApplicationImpl) {
application.threadingSupport.releaseTheAcquiredWriteIntentLockThenExecuteActionAndTakeWriteIntentLockBack(runnable)
}
else {
runnable()
}
}
while (dispatchAllEventsInIdeEventQueue()) // make sure that all the scheduled write actions are executed
}

View File

@@ -555,7 +555,7 @@
<stacktrace.fold substring="at com.intellij.openapi.application.TransactionGuardImpl"/>
<stacktrace.fold substring="at com.intellij.openapi.application.WriteAction."/>
<stacktrace.fold substring="at com.intellij.openapi.application.impl.AnyThreadWriteThreadingSupport"/>
<stacktrace.fold substring="at com.intellij.openapi.application.impl.NestedLocksThreadingSupport"/>
<stacktrace.fold substring="at com.intellij.platform.locking.impl.NestedLocksThreadingSupport"/>
<stacktrace.fold substring="at com.intellij.openapi.application.impl.ApplicationImpl$1.call("/>
<stacktrace.fold substring="at com.intellij.openapi.application.impl.ApplicationImpl$2.run"/>
<stacktrace.fold substring="at com.intellij.openapi.application.impl.ApplicationImpl.runReadAction("/>