diff --git a/platform/core-api/api-dump.txt b/platform/core-api/api-dump.txt
index 39d3fc684fe3..a6877507e0f3 100644
--- a/platform/core-api/api-dump.txt
+++ b/platform/core-api/api-dump.txt
@@ -1745,6 +1745,8 @@ com.intellij.util.QueryExecutor
com.intellij.util.QueryParameters
- getProject():com.intellij.openapi.project.Project
- isQueryValid():Z
+f:com.intellij.util.concurrency.ThreadingAssertions
+- s:softAssertNoReadAccess():V
com.intellij.util.download.DownloadableFileDescription
- a:generateFileName(com.intellij.openapi.util.Condition):java.lang.String
- a:getDefaultFileName():java.lang.String
diff --git a/platform/core-api/src/com/intellij/util/concurrency/ThreadingAssertions.java b/platform/core-api/src/com/intellij/util/concurrency/ThreadingAssertions.java
index 3dd0ea04fca6..bfc9702d0030 100644
--- a/platform/core-api/src/com/intellij/util/concurrency/ThreadingAssertions.java
+++ b/platform/core-api/src/com/intellij/util/concurrency/ThreadingAssertions.java
@@ -178,6 +178,19 @@ public final class ThreadingAssertions {
}
}
+ /**
+ * Asserts that the current thread has no read access without throwing an exception.
+ *
+ * @see com.intellij.util.concurrency.annotations.RequiresReadLockAbsence
+ */
+ @Obsolete
+ public static void softAssertNoReadAccess() {
+ Application application = ApplicationManager.getApplication();
+ if (application != null && application.isReadAccessAllowed()) {
+ getLogger().error(createThreadAccessException(MUST_NOT_EXECUTE_IN_READ_ACTION));
+ }
+ }
+
/**
* Asserts that the current thread has no read access local to this thread (non-inherited).
*/
diff --git a/platform/execution-impl/src/com/intellij/terminal/ui/TerminalWidget.kt b/platform/execution-impl/src/com/intellij/terminal/ui/TerminalWidget.kt
index 37069b482815..ff7e696091fc 100644
--- a/platform/execution-impl/src/com/intellij/terminal/ui/TerminalWidget.kt
+++ b/platform/execution-impl/src/com/intellij/terminal/ui/TerminalWidget.kt
@@ -78,8 +78,8 @@ interface TerminalWidget : ComponentContainer {
* so it is prohibited to call it on EDT or under read action.
*/
@ApiStatus.Experimental
- @RequiresReadLockAbsence
- @RequiresBackgroundThread
+ @RequiresReadLockAbsence(generateAssertion = false)
+ @RequiresBackgroundThread(generateAssertion = false)
fun isCommandRunning(): Boolean {
return false
}
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/ShellTerminalWidget.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/ShellTerminalWidget.java
index ac3b6167fad6..ba1c94982a37 100644
--- a/plugins/terminal/src/org/jetbrains/plugins/terminal/ShellTerminalWidget.java
+++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/ShellTerminalWidget.java
@@ -207,8 +207,8 @@ public class ShellTerminalWidget extends JBTerminalWidget implements TerminalPan
* so it is prohibited to call it on EDT or under read action.
*/
@Override
- @RequiresReadLockAbsence
- @RequiresBackgroundThread
+ @RequiresReadLockAbsence(generateAssertion = false)
+ @RequiresBackgroundThread(generateAssertion = false)
public boolean hasRunningCommands() throws IllegalStateException {
TtyConnector connector = getTtyConnector();
if (connector == null) return false;
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalUtil.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalUtil.java
index a5990a094be0..2cd085d95cb7 100644
--- a/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalUtil.java
+++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalUtil.java
@@ -12,6 +12,7 @@ import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.remote.RemoteSshProcess;
import com.intellij.ui.ExperimentalUI;
+import com.intellij.util.concurrency.ThreadingAssertions;
import com.intellij.util.concurrency.annotations.RequiresBackgroundThread;
import com.intellij.util.concurrency.annotations.RequiresReadLockAbsence;
import com.intellij.util.containers.ContainerUtil;
@@ -44,9 +45,13 @@ public final class TerminalUtil {
* This method may access the file system and launch external processes,
* so it is prohibited to call it on EDT or under read action.
*/
- @RequiresReadLockAbsence
- @RequiresBackgroundThread
+ @SuppressWarnings("UsagesOfObsoleteApi") // Can't use just only annotations because they generate throwing assertions
+ @RequiresReadLockAbsence(generateAssertion = false)
+ @RequiresBackgroundThread(generateAssertion = false)
public static boolean hasRunningCommands(@NotNull TtyConnector connector) throws IllegalStateException {
+ ThreadingAssertions.softAssertBackgroundThread();
+ ThreadingAssertions.softAssertNoReadAccess();
+
if (!connector.isConnected()) return false;
ProcessTtyConnector processTtyConnector = ShellTerminalWidget.getProcessTtyConnector(connector);
if (processTtyConnector == null) return true;