From 03dce4a75631186110eabf859a1209c46c64fec3 Mon Sep 17 00:00:00 2001 From: Konstantin Nisht Date: Wed, 11 Jun 2025 17:41:52 +0200 Subject: [PATCH] [threading] IJPL-148438: Extract implementation for locks to a separate module GitOrigin-RevId: 4f501adff06ed8c9de63b85c652b888df4487e11 --- .idea/modules.xml | 1 + platform/locking.impl/BUILD.bazel | 20 ++++++++++++++++++ platform/locking.impl/api-dump.txt | 0 .../intellij.platform.locking.impl.iml | 19 +++++++++++++++++ .../src}/NestedLocksThreadingSupport.kt | 21 +++++++------------ platform/locking.impl/src/util.kt | 18 ++++++++++++++++ platform/platform-impl/BUILD.bazel | 4 ++-- .../intellij.platform.ide.impl.iml | 2 +- .../src/com/intellij/ide/IdeEventQueue.kt | 2 +- .../intellij/ide/IdeKeyboardFocusManager.kt | 2 +- .../openapi/actionSystem/impl/Utils.kt | 2 +- .../application/impl/ApplicationImpl.java | 21 ++++++++++--------- .../impl/NonBlockingReadActionImpl.java | 3 ++- .../openapi/application/impl/appImpl.kt | 11 ---------- .../application/rw/InternalReadAction.kt | 2 +- .../openapi/progress/util/SuvorovProgress.kt | 2 +- .../ui/impl/DialogWrapperPeerImpl.java | 4 ++-- .../openapi/wm/impl/FocusManagerImpl.java | 8 ++++--- platform/platform-tests/BUILD.bazel | 1 + .../intellij.platform.tests.iml | 1 + .../impl/BackgroundWriteActionTest.kt | 1 + .../application/impl/PlatformUtilitiesTest.kt | 1 + .../impl/ReadWritePropagationTest.kt | 7 +++++-- .../progress/RunBlockingCancellableTest.kt | 2 +- .../testFramework/IndexingTestUtil.kt | 15 +++++++++---- .../resources/intellij.devkit.core.xml | 2 +- 26 files changed, 116 insertions(+), 56 deletions(-) create mode 100644 platform/locking.impl/BUILD.bazel create mode 100644 platform/locking.impl/api-dump.txt create mode 100644 platform/locking.impl/intellij.platform.locking.impl.iml rename platform/{platform-impl/src/com/intellij/openapi/application/impl => locking.impl/src}/NestedLocksThreadingSupport.kt (99%) create mode 100644 platform/locking.impl/src/util.kt diff --git a/.idea/modules.xml b/.idea/modules.xml index b2ba33f346a8..b39b2d000b72 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -861,6 +861,7 @@ + diff --git a/platform/locking.impl/BUILD.bazel b/platform/locking.impl/BUILD.bazel new file mode 100644 index 000000000000..78105fe37a9e --- /dev/null +++ b/platform/locking.impl/BUILD.bazel @@ -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 \ No newline at end of file diff --git a/platform/locking.impl/api-dump.txt b/platform/locking.impl/api-dump.txt new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/platform/locking.impl/intellij.platform.locking.impl.iml b/platform/locking.impl/intellij.platform.locking.impl.iml new file mode 100644 index 000000000000..8771a4b5931f --- /dev/null +++ b/platform/locking.impl/intellij.platform.locking.impl.iml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/openapi/application/impl/NestedLocksThreadingSupport.kt b/platform/locking.impl/src/NestedLocksThreadingSupport.kt similarity index 99% rename from platform/platform-impl/src/com/intellij/openapi/application/impl/NestedLocksThreadingSupport.kt rename to platform/locking.impl/src/NestedLocksThreadingSupport.kt index 756f4907f7ba..fdb03b01a4d4 100644 --- a/platform/platform-impl/src/com/intellij/openapi/application/impl/NestedLocksThreadingSupport.kt +++ b/platform/locking.impl/src/NestedLocksThreadingSupport.kt @@ -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 { diff --git a/platform/locking.impl/src/util.kt b/platform/locking.impl/src/util.kt new file mode 100644 index 000000000000..2324adb0f6a6 --- /dev/null +++ b/platform/locking.impl/src/util.kt @@ -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 +} \ No newline at end of file diff --git a/platform/platform-impl/BUILD.bazel b/platform/platform-impl/BUILD.bazel index 728564fefd64..87f1013dcb81 100644 --- a/platform/platform-impl/BUILD.bazel +++ b/platform/platform-impl/BUILD.bazel @@ -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"] ) diff --git a/platform/platform-impl/intellij.platform.ide.impl.iml b/platform/platform-impl/intellij.platform.ide.impl.iml index 2ac98e2bbc74..bf851e5ec720 100644 --- a/platform/platform-impl/intellij.platform.ide.impl.iml +++ b/platform/platform-impl/intellij.platform.ide.impl.iml @@ -133,7 +133,6 @@ - @@ -164,5 +163,6 @@ + \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.kt b/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.kt index ae94c0522d22..b4ecba945e32 100644 --- a/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.kt +++ b/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.kt @@ -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 diff --git a/platform/platform-impl/src/com/intellij/ide/IdeKeyboardFocusManager.kt b/platform/platform-impl/src/com/intellij/ide/IdeKeyboardFocusManager.kt index 7dd1b83b3944..be82da2f17f0 100644 --- a/platform/platform-impl/src/com/intellij/ide/IdeKeyboardFocusManager.kt +++ b/platform/platform-impl/src/com/intellij/ide/IdeKeyboardFocusManager.kt @@ -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 diff --git a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/Utils.kt b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/Utils.kt index 6a319f36e9da..84c2837f7d4c 100644 --- a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/Utils.kt +++ b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/Utils.kt @@ -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 diff --git a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java index e73ce8aee3a0..c75c68e0f88e 100644 --- a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java @@ -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 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) diff --git a/platform/platform-impl/src/com/intellij/openapi/application/impl/NonBlockingReadActionImpl.java b/platform/platform-impl/src/com/intellij/openapi/application/impl/NonBlockingReadActionImpl.java index a1b45f06ade6..273b32edf96e 100644 --- a/platform/platform-impl/src/com/intellij/openapi/application/impl/NonBlockingReadActionImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/application/impl/NonBlockingReadActionImpl.java @@ -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 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; diff --git a/platform/platform-impl/src/com/intellij/openapi/application/impl/appImpl.kt b/platform/platform-impl/src/com/intellij/openapi/application/impl/appImpl.kt index 4664a13ead4c..26770ebaa812 100644 --- a/platform/platform-impl/src/com/intellij/openapi/application/impl/appImpl.kt +++ b/platform/platform-impl/src/com/intellij/openapi/application/impl/appImpl.kt @@ -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 diff --git a/platform/platform-impl/src/com/intellij/openapi/application/rw/InternalReadAction.kt b/platform/platform-impl/src/com/intellij/openapi/application/rw/InternalReadAction.kt index c1b60f1e4984..64daca9de18d 100644 --- a/platform/platform-impl/src/com/intellij/openapi/application/rw/InternalReadAction.kt +++ b/platform/platform-impl/src/com/intellij/openapi/application/rw/InternalReadAction.kt @@ -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 diff --git a/platform/platform-impl/src/com/intellij/openapi/progress/util/SuvorovProgress.kt b/platform/platform-impl/src/com/intellij/openapi/progress/util/SuvorovProgress.kt index 504c0aa362e0..3aacbc91dd52 100644 --- a/platform/platform-impl/src/com/intellij/openapi/progress/util/SuvorovProgress.kt +++ b/platform/platform-impl/src/com/intellij/openapi/progress/util/SuvorovProgress.kt @@ -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 diff --git a/platform/platform-impl/src/com/intellij/openapi/ui/impl/DialogWrapperPeerImpl.java b/platform/platform-impl/src/com/intellij/openapi/ui/impl/DialogWrapperPeerImpl.java index 1fb01cf24a89..84e3c4e118a3 100644 --- a/platform/platform-impl/src/com/intellij/openapi/ui/impl/DialogWrapperPeerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/ui/impl/DialogWrapperPeerImpl.java @@ -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(); } diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusManagerImpl.java index c2b1b1795603..b01fdcfaf89a 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusManagerImpl.java @@ -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; }); diff --git a/platform/platform-tests/BUILD.bazel b/platform/platform-tests/BUILD.bazel index 7a1b03d9d390..44a1c7df2d91 100644 --- a/platform/platform-tests/BUILD.bazel +++ b/platform/platform-tests/BUILD.bazel @@ -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", diff --git a/platform/platform-tests/intellij.platform.tests.iml b/platform/platform-tests/intellij.platform.tests.iml index 59118e96da6b..85cf5efcc644 100644 --- a/platform/platform-tests/intellij.platform.tests.iml +++ b/platform/platform-tests/intellij.platform.tests.iml @@ -143,5 +143,6 @@ + \ No newline at end of file diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/application/impl/BackgroundWriteActionTest.kt b/platform/platform-tests/testSrc/com/intellij/openapi/application/impl/BackgroundWriteActionTest.kt index 3c7180c353f0..12bb8130b3e6 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/application/impl/BackgroundWriteActionTest.kt +++ b/platform/platform-tests/testSrc/com/intellij/openapi/application/impl/BackgroundWriteActionTest.kt @@ -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 diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/application/impl/PlatformUtilitiesTest.kt b/platform/platform-tests/testSrc/com/intellij/openapi/application/impl/PlatformUtilitiesTest.kt index cc06ef8f3c7a..b3bc2956fde1 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/application/impl/PlatformUtilitiesTest.kt +++ b/platform/platform-tests/testSrc/com/intellij/openapi/application/impl/PlatformUtilitiesTest.kt @@ -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 diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/application/impl/ReadWritePropagationTest.kt b/platform/platform-tests/testSrc/com/intellij/openapi/application/impl/ReadWritePropagationTest.kt index eea41ee349f6..9b006a43d051 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/application/impl/ReadWritePropagationTest.kt +++ b/platform/platform-tests/testSrc/com/intellij/openapi/application/impl/ReadWritePropagationTest.kt @@ -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 diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/progress/RunBlockingCancellableTest.kt b/platform/platform-tests/testSrc/com/intellij/openapi/progress/RunBlockingCancellableTest.kt index 735ca4e50d16..56a554008328 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/progress/RunBlockingCancellableTest.kt +++ b/platform/platform-tests/testSrc/com/intellij/openapi/progress/RunBlockingCancellableTest.kt @@ -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 diff --git a/platform/testFramework/src/com/intellij/testFramework/IndexingTestUtil.kt b/platform/testFramework/src/com/intellij/testFramework/IndexingTestUtil.kt index 561ecf93d386..66428feb1908 100644 --- a/platform/testFramework/src/com/intellij/testFramework/IndexingTestUtil.kt +++ b/platform/testFramework/src/com/intellij/testFramework/IndexingTestUtil.kt @@ -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 } diff --git a/plugins/devkit/devkit-core/resources/intellij.devkit.core.xml b/plugins/devkit/devkit-core/resources/intellij.devkit.core.xml index 0a64fa91aa98..cf5651a51346 100644 --- a/plugins/devkit/devkit-core/resources/intellij.devkit.core.xml +++ b/plugins/devkit/devkit-core/resources/intellij.devkit.core.xml @@ -555,7 +555,7 @@ - +