[threading] IJPL-148438: Hide LockAcquisitionListener to the impl module

GitOrigin-RevId: 4d2fc42735fd1659eeaedca8e86fa7ded0cbce56
This commit is contained in:
Konstantin Nisht
2025-06-12 12:16:14 +02:00
committed by intellij-monorepo-bot
parent 7e4277f58e
commit da2df09cfa
7 changed files with 28 additions and 45 deletions

View File

@@ -185,16 +185,6 @@ interface ThreadingSupport {
*/
fun prohibitWriteActionsInside(): CleanupAction
/**
* Adds a [LockAcquisitionListener].
*
* Only one listener can be set. It is an error to set the second listener.
*
* @param listener the listener to set
*/
@ApiStatus.Internal
fun setLockAcquisitionListener(listener: LockAcquisitionListener)
@ApiStatus.Internal
fun setLockAcquisitionInterceptor(consumer: (Deferred<*>) -> Unit)
@@ -213,17 +203,6 @@ interface ThreadingSupport {
@ApiStatus.Internal
fun removeLegacyIndicatorProvider(provider: LegacyProgressIndicatorProvider)
/**
* Removes a [LockAcquisitionListener].
*
* It is error to remove listener which was not set early.
*
* @param listener the listener to remove
*/
@ApiStatus.Internal
fun removeLockAcquisitionListener(listener: LockAcquisitionListener)
/**
* Prevents any attempt to use R/W locks inside [action].
*/

View File

@@ -227,9 +227,6 @@ public interface ApplicationEx extends Application {
@ApiStatus.Internal
default void addWriteIntentReadActionListener(@NotNull WriteIntentReadActionListener listener, @NotNull Disposable parentDisposable) { }
@ApiStatus.Internal
default void addLockAcquisitionListener(@NotNull LockAcquisitionListener listener, @NotNull Disposable parentDisposable) { }
@ApiStatus.Internal
@ApiStatus.Obsolete
default void addSuspendingWriteActionListener(@NotNull WriteLockReacquisitionListener listener, @NotNull Disposable parentDisposable) { }

View File

@@ -9,6 +9,7 @@ import com.intellij.openapi.application.*
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.progress.Cancellation
import com.intellij.openapi.util.text.StringUtil
import com.intellij.platform.locking.impl.listeners.LockAcquisitionListener
import com.intellij.util.ReflectionUtil
import kotlinx.coroutines.*
import kotlinx.coroutines.internal.intellij.IntellijCoroutines
@@ -146,7 +147,7 @@ private data class ExposedWritePermitData(
* It actually helps to resolve certain kind of deadlocks.
*/
@ApiStatus.Internal
internal class NestedLocksThreadingSupport : ThreadingSupport {
class NestedLocksThreadingSupport : ThreadingSupport {
companion object {
private const val SPIN_TO_WAIT_FOR_LOCK: Int = 100
private val logger = Logger.getInstance(NestedLocksThreadingSupport::class.java)
@@ -810,8 +811,7 @@ internal class NestedLocksThreadingSupport : ThreadingSupport {
myWriteActionListener = null
}
@ApiStatus.Internal
override fun setLockAcquisitionListener(listener: LockAcquisitionListener) {
fun setLockAcquisitionListener(listener: LockAcquisitionListener) {
if (myLockAcquisitionListener != null)
error("LockAcquisitionListener already registered")
myLockAcquisitionListener = listener
@@ -855,8 +855,7 @@ internal class NestedLocksThreadingSupport : ThreadingSupport {
myLegacyProgressIndicatorProvider = null
}
@ApiStatus.Internal
override fun removeLockAcquisitionListener(listener: LockAcquisitionListener) {
fun removeLockAcquisitionListener(listener: LockAcquisitionListener) {
if (myLockAcquisitionListener != listener)
error("LockAcquisitionListener is not registered")
myLockAcquisitionListener = null

View File

@@ -1,8 +1,8 @@
// 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
package com.intellij.platform.locking.impl.listeners
import org.jetbrains.annotations.ApiStatus
import java.util.EventListener
import java.util.*
/**
* Provides the possibility to react to the acquisition and release of the RWI lock.

View File

@@ -15,4 +15,9 @@ fun newLockingSupport(): ThreadingSupport =
@ApiStatus.Internal
fun getGlobalThreadingSupport(): ThreadingSupport {
return instance
}
@ApiStatus.Internal
fun getGlobalNestedLockingThreadingSupport(): NestedLocksThreadingSupport {
return instance
}

View File

@@ -2,13 +2,13 @@
package com.intellij.diagnostic
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.LockAcquisitionListener
import com.intellij.openapi.application.ThreadingSupport
import com.intellij.openapi.application.WriteDelayDiagnostics
import com.intellij.openapi.application.ex.ApplicationEx
import com.intellij.openapi.application.ex.ApplicationManagerEx
import com.intellij.openapi.application.impl.ApplicationImpl
import com.intellij.openapi.diagnostic.ControlFlowException
import com.intellij.openapi.diagnostic.Logger
import com.intellij.platform.locking.impl.listeners.LockAcquisitionListener
import com.intellij.util.asDisposable
import com.intellij.util.concurrency.AppExecutorUtil
import kotlinx.coroutines.CoroutineScope
@@ -20,7 +20,7 @@ import java.util.concurrent.TimeUnit
class WriteLockMeasurerImpl(scope: CoroutineScope) : WriteLockMeasurer {
init {
val application = ApplicationManager.getApplication()
if (application is ApplicationEx) {
if (application is ApplicationImpl) {
application.addLockAcquisitionListener(WriteLockMeasurementListener(), scope.asDisposable())
}
}

View File

@@ -45,6 +45,8 @@ 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.platform.locking.impl.NestedLocksThreadingSupport;
import com.intellij.platform.locking.impl.listeners.LockAcquisitionListener;
import com.intellij.psi.util.ReadActionCache;
import com.intellij.ui.ComponentUtil;
import com.intellij.util.*;
@@ -112,6 +114,8 @@ public final class ApplicationImpl extends ClientAwareComponentManager implement
// contents modified in write action, read in read action
private final TransactionGuardImpl myTransactionGuard = new TransactionGuardImpl();
private final NestedLocksThreadingSupport lock = IntelliJLockingUtil.getGlobalNestedLockingThreadingSupport();
private final ReadActionCacheImpl myReadActionCacheImpl = new ReadActionCacheImpl();
private final ThreadLocal<Boolean> myImpatientReader = ThreadLocal.withInitial(() -> false);
@@ -388,7 +392,7 @@ public final class ApplicationImpl extends ClientAwareComponentManager implement
getThreadingSupport().removeReadActionListener(myLockDispatcherListener);
getThreadingSupport().removeWriteActionListener(myLockDispatcherListener);
getThreadingSupport().removeWriteIntentReadActionListener(myLockDispatcherListener);
getThreadingSupport().removeLockAcquisitionListener(myLockDispatcherListener);
lock.removeLockAcquisitionListener(myLockDispatcherListener);
getThreadingSupport().removeWriteLockReacquisitionListener(myLockDispatcherListener);
getThreadingSupport().removeLegacyIndicatorProvider(myLegacyIndicatorProvider);
@@ -1005,14 +1009,14 @@ public final class ApplicationImpl extends ClientAwareComponentManager implement
return runEdtProgressWriteAction(title, project, parentComponent, IdeBundle.message("action.stop"), action);
}
private static boolean runEdtProgressWriteAction(
private boolean runEdtProgressWriteAction(
@NlsContexts.ProgressTitle String title,
@Nullable Project project,
@Nullable JComponent parentComponent,
@Nls(capitalization = Nls.Capitalization.Title) @Nullable String cancelText,
@NotNull Consumer<? super @Nullable ProgressIndicator> action
) {
return IntelliJLockingUtil.getGlobalThreadingSupport().runWriteAction(action.getClass(), () -> {
return lock.runWriteAction(action.getClass(), () -> {
var indicator = new PotemkinProgress(title, project, parentComponent, cancelText);
indicator.runInSwingThread(() -> {
action.accept(indicator);
@@ -1377,16 +1381,16 @@ public final class ApplicationImpl extends ClientAwareComponentManager implement
return true;
}, app.getCoroutineScope());
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);
app.lock.setReadActionListener(app.myLockDispatcherListener);
app.lock.setWriteActionListener(app.myLockDispatcherListener);
app.lock.setWriteIntentReadActionListener(app.myLockDispatcherListener);
app.lock.setLockAcquisitionListener(app.myLockDispatcherListener);
app.lock.setWriteLockReacquisitionListener(app.myLockDispatcherListener);
app.lock.setLegacyIndicatorProvider(myLegacyIndicatorProvider);
if (ThreadingRuntimeFlagsKt.getInstallSuvorovProgress()) {
SwingUtilities.invokeLater(() -> {
SuvorovProgress.INSTANCE.init(app);
app.getThreadingSupport().setLockAcquisitionInterceptor((deferred) -> {
app.lock.setLockAcquisitionInterceptor((deferred) -> {
SuvorovProgress.dispatchEventsUntilComputationCompletes(deferred);
return Unit.INSTANCE;
});
@@ -1425,7 +1429,6 @@ public final class ApplicationImpl extends ClientAwareComponentManager implement
myLockDispatcherListener.addWriteIntentReadActionListener(listener, parentDisposable);
}
@Override
public void addLockAcquisitionListener(@NotNull LockAcquisitionListener listener, @NotNull Disposable parentDisposable) {
myLockDispatcherListener.addLockAcquisitionListener(listener, parentDisposable);
}