mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-13 15:52:01 +07:00
PY-76036 PY-75988 PY-75990 PY-76065: Fix various threading issues after the new platform threading policy
All "implicit" locks are removed from the platform, so we need to call read/write action explicitly (which is a right thing to do in any case). GitOrigin-RevId: 290788bc78e39ca42f7d0f14ae4ccd16dd315ce7
This commit is contained in:
committed by
intellij-monorepo-bot
parent
888e3be3de
commit
0438f8093b
@@ -46,8 +46,10 @@ import java.util.Map;
|
||||
* Needs not to be instantiated and only holds static methods.
|
||||
*
|
||||
* @see PythonSdkUtil for Pyhton SDK utilities with no run-time dependencies
|
||||
*
|
||||
* @deprecated please use Kotlin coroutines to run processes in background
|
||||
*/
|
||||
//TODO: rename to PySdkExecuteUtil or PySdkRuntimeUtil
|
||||
@Deprecated
|
||||
public final class PySdkUtil {
|
||||
private static final Logger LOG = Logger.getInstance(PySdkUtil.class);
|
||||
|
||||
|
||||
@@ -334,6 +334,7 @@ public abstract class PythonSdkFlavor<D extends PyFlavorData> {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@RequiresBackgroundThread(generateAssertion = false) //because of process output
|
||||
public String getVersionString(@Nullable String sdkHome) {
|
||||
if (sdkHome == null) {
|
||||
return null;
|
||||
@@ -394,6 +395,7 @@ public abstract class PythonSdkFlavor<D extends PyFlavorData> {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@RequiresBackgroundThread(generateAssertion = false) //because of process output
|
||||
public LanguageLevel getLanguageLevel(@NotNull String sdkHome) {
|
||||
return getLanguageLevelFromVersionString(getVersionString(sdkHome));
|
||||
}
|
||||
|
||||
@@ -5,9 +5,9 @@ import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.application.EDT
|
||||
import com.intellij.openapi.application.ModalityState
|
||||
import com.intellij.openapi.application.asContextElement
|
||||
import com.intellij.openapi.application.writeIntentReadAction
|
||||
import com.intellij.openapi.components.Service
|
||||
import com.intellij.openapi.components.service
|
||||
import com.intellij.util.concurrency.ThreadingAssertions
|
||||
import com.intellij.util.concurrency.annotations.RequiresBlockingContext
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -25,6 +25,11 @@ private class MyService(val coroutineScope: CoroutineScope)
|
||||
@RequiresBlockingContext
|
||||
internal fun <T : Any> Flow<T>.oneShotConsumer(consumer: Consumer<T>) {
|
||||
ApplicationManager.getApplication().service<MyService>().coroutineScope.launch(Dispatchers.EDT + ModalityState.defaultModalityState().asContextElement()) {
|
||||
consumer.accept(this@oneShotConsumer.first())
|
||||
// Platform doesn't guarantee write intent lock on EDT
|
||||
//todo fix all clients and remove global lock from here
|
||||
val t = this@oneShotConsumer.first()
|
||||
writeIntentReadAction {
|
||||
consumer.accept(t)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,11 +17,7 @@ package com.jetbrains.python.sdk
|
||||
|
||||
import com.intellij.execution.ExecutionException
|
||||
import com.intellij.execution.target.*
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.application.PathManager
|
||||
import com.intellij.openapi.application.WriteAction
|
||||
import com.intellij.openapi.application.invokeAndWaitIfNeeded
|
||||
import com.intellij.openapi.application.runInEdt
|
||||
import com.intellij.openapi.application.*
|
||||
import com.intellij.openapi.diagnostic.getOrLogException
|
||||
import com.intellij.openapi.diagnostic.thisLogger
|
||||
import com.intellij.openapi.module.Module
|
||||
@@ -43,7 +39,10 @@ import com.intellij.openapi.vfs.LocalFileSystem
|
||||
import com.intellij.openapi.vfs.StandardFileSystems
|
||||
import com.intellij.openapi.vfs.VfsUtil
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.platform.ide.progress.ModalTaskOwner
|
||||
import com.intellij.platform.ide.progress.runWithModalProgressBlocking
|
||||
import com.intellij.util.PathUtil
|
||||
import com.intellij.util.concurrency.annotations.RequiresBackgroundThread
|
||||
import com.intellij.webcore.packaging.PackagesNotificationPanel
|
||||
import com.jetbrains.extensions.failure
|
||||
import com.jetbrains.python.PyBundle
|
||||
@@ -59,12 +58,16 @@ import com.jetbrains.python.sdk.flavors.VirtualEnvSdkFlavor
|
||||
import com.jetbrains.python.sdk.flavors.conda.CondaEnvSdkFlavor
|
||||
import com.jetbrains.python.target.PyTargetAwareAdditionalData
|
||||
import com.jetbrains.python.ui.PyUiUtil
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import java.nio.file.Paths
|
||||
import javax.swing.SwingUtilities
|
||||
import kotlin.Result
|
||||
import kotlin.io.path.div
|
||||
import kotlin.io.path.pathString
|
||||
|
||||
@@ -187,13 +190,22 @@ fun createSdkByGenerateTask(
|
||||
throw e
|
||||
}
|
||||
|
||||
val suggestedName = suggestedSdkName ?: suggestAssociatedSdkName(homeFile.path, associatedProjectPath)
|
||||
val sdkName = suggestedSdkName ?: if (SwingUtilities.isEventDispatchThread()) {
|
||||
runWithModalProgressBlocking(ModalTaskOwner.guess(), "...") {
|
||||
withContext(Dispatchers.IO) {
|
||||
suggestAssociatedSdkName(homeFile.path, associatedProjectPath)
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
suggestAssociatedSdkName(homeFile.path, associatedProjectPath)
|
||||
}
|
||||
return SdkConfigurationUtil.setupSdk(
|
||||
existingSdks.toTypedArray(),
|
||||
homeFile,
|
||||
PythonSdkType.getInstance(),
|
||||
null,
|
||||
suggestedName)
|
||||
sdkName)
|
||||
}
|
||||
|
||||
fun showSdkExecutionException(sdk: Sdk?, e: ExecutionException, @NlsContexts.DialogTitle title: String) {
|
||||
@@ -378,6 +390,7 @@ fun getInnerVirtualEnvRoot(sdk: Sdk): VirtualFile? {
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresBackgroundThread
|
||||
internal fun suggestAssociatedSdkName(sdkHome: String, associatedPath: String?): String? {
|
||||
// please don't forget to update com.jetbrains.python.inspections.PyInterpreterInspection.Visitor#getSuitableSdkFix
|
||||
// after changing this method
|
||||
|
||||
@@ -33,6 +33,7 @@ import com.intellij.remote.ext.LanguageCaseCollector;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.ExceptionUtil;
|
||||
import com.intellij.util.PlatformUtils;
|
||||
import com.intellij.util.concurrency.annotations.RequiresBackgroundThread;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.PyNames;
|
||||
@@ -244,7 +245,7 @@ public final class PythonSdkType extends SdkType {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresBackgroundThread(generateAssertion = false) //because of process output
|
||||
public static @Nullable String suggestBaseSdkName(@NotNull String sdkHome) {
|
||||
final PythonSdkFlavor flavor = PythonSdkFlavor.getFlavor(sdkHome);
|
||||
if (flavor == null) return null;
|
||||
|
||||
@@ -3,12 +3,13 @@ package com.jetbrains.python.sdk.add.v2
|
||||
|
||||
import com.intellij.execution.ExecutionException
|
||||
import com.intellij.openapi.application.EDT
|
||||
import com.intellij.openapi.application.writeAction
|
||||
import com.intellij.openapi.module.ModuleUtil
|
||||
import com.intellij.openapi.project.ProjectManager
|
||||
import com.intellij.openapi.projectRoots.ProjectJdkTable
|
||||
import com.intellij.openapi.projectRoots.Sdk
|
||||
import com.intellij.openapi.projectRoots.impl.SdkConfigurationUtil
|
||||
import com.intellij.openapi.vfs.StandardFileSystems
|
||||
import com.intellij.openapi.vfs.VfsUtil
|
||||
import com.intellij.platform.ide.progress.ModalTaskOwner
|
||||
import com.intellij.platform.ide.progress.TaskCancellation
|
||||
import com.intellij.platform.ide.progress.withModalProgress
|
||||
@@ -53,13 +54,16 @@ suspend fun PythonMutableTargetAddInterpreterModel.setupVirtualenv(venvPath: Pat
|
||||
catch (e: InvalidPathException) {
|
||||
return Result.failure(e)
|
||||
}
|
||||
val venvPython = VirtualEnvReader.Instance.findPythonInPythonRoot(dir)?.toString()
|
||||
val venvPython = VirtualEnvReader.Instance.findPythonInPythonRoot(dir)
|
||||
if (venvPython == null) {
|
||||
return failure(message("commandLine.directoryCantBeAccessed", venvPathOnTarget))
|
||||
}
|
||||
|
||||
val homeFile = try {
|
||||
StandardFileSystems.local().refreshAndFindFileByPath(venvPython)
|
||||
// refresh needs write action
|
||||
writeAction {
|
||||
VfsUtil.findFile(venvPython, true)
|
||||
}
|
||||
}
|
||||
catch (e: ExecutionException) {
|
||||
return Result.failure(e)
|
||||
@@ -68,10 +72,13 @@ suspend fun PythonMutableTargetAddInterpreterModel.setupVirtualenv(venvPath: Pat
|
||||
return failure(message("commandLine.directoryCantBeAccessed", venvPathOnTarget))
|
||||
}
|
||||
|
||||
val suggestedName = /*suggestedSdkName ?:*/ suggestAssociatedSdkName(homeFile.path, projectPath.toString())
|
||||
val newSdk = SdkConfigurationUtil.setupSdk(existingSdks.toTypedArray(), homeFile,
|
||||
PythonSdkType.getInstance(),
|
||||
false, null, suggestedName)!!
|
||||
// "suggest name" calls external process and can't be called from EDT
|
||||
val newSdk = withContext(Dispatchers.IO) {
|
||||
val suggestedName = /*suggestedSdkName ?:*/ suggestAssociatedSdkName(homeFile.path, projectPath.toString())
|
||||
SdkConfigurationUtil.setupSdk(existingSdks.toTypedArray(), homeFile,
|
||||
PythonSdkType.getInstance(),
|
||||
false, null, suggestedName)!!
|
||||
}
|
||||
|
||||
addSdk(newSdk)
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ package com.jetbrains.python.util
|
||||
import com.intellij.openapi.application.EDT
|
||||
import com.intellij.openapi.application.ModalityState
|
||||
import com.intellij.openapi.application.asContextElement
|
||||
import com.intellij.openapi.application.writeIntentReadAction
|
||||
import com.intellij.openapi.diagnostic.thisLogger
|
||||
import com.intellij.openapi.ui.Messages
|
||||
import com.intellij.openapi.util.NlsSafe
|
||||
@@ -56,7 +57,10 @@ object ShowingMessageErrorSync : ErrorSink {
|
||||
override suspend fun emit(value: @NlsSafe String) {
|
||||
withContext(Dispatchers.EDT + ModalityState.any().asContextElement()) {
|
||||
thisLogger().warn(value)
|
||||
Messages.showErrorDialog(value, PyBundle.message("python.error"))
|
||||
// Platform doesn't allow dialogs without lock for now, fix later
|
||||
writeIntentReadAction {
|
||||
Messages.showErrorDialog(value, PyBundle.message("python.error"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user