fix: Make EDT coroutine modality state explicit everywhere and fix deadlocks

This commit is contained in:
FalsePattern 2025-03-27 22:02:33 +01:00
parent 6c14ad7113
commit 1f79f484e5
Signed by: falsepattern
GPG key ID: E930CDEC50C50E23
8 changed files with 15 additions and 11 deletions

View file

@ -34,6 +34,7 @@ Changelog structure reference:
- Project
- File path browse buttons in zig run configurations didn't work
- Occasional GUI deadlocks
- Zig
- IPC wrapper wasn't passing exit code

View file

@ -93,7 +93,7 @@ abstract class ZigDebugRunnerBase<ProfileState : ZigProfileState<*>> : ZigProgra
}
}
}
return@reportProgress runInterruptibleEDT {
return@reportProgress runInterruptibleEDT(ModalityState.any()) {
val debuggerManager = XDebuggerManager.getInstance(environment.project)
debuggerManager.startSession(environment, object: XDebugProcessStarter() {
override fun start(session: XDebugSession): XDebugProcess {

View file

@ -31,6 +31,7 @@ import com.falsepattern.zigbrains.shared.coroutine.launchWithEDT
import com.falsepattern.zigbrains.shared.coroutine.runModalOrBlocking
import com.falsepattern.zigbrains.shared.zigCoroutineScope
import com.intellij.ide.plugins.PluginManager
import com.intellij.openapi.application.ModalityState
import com.intellij.openapi.extensions.PluginId
import com.intellij.openapi.observable.util.whenItemSelected
import com.intellij.openapi.ui.ComboBox
@ -88,7 +89,7 @@ class ZigDebuggerToolchainConfigurableUi : ZigDebuggerUiComponent {
row(ZigDebugBundle.message("settings.debugger.toolchain.debugger.label")) {
comment = cell(debuggerKindComboBox)
.comment("", DEFAULT_COMMENT_WIDTH) {
zigCoroutineScope.launchWithEDT {
zigCoroutineScope.launchWithEDT(ModalityState.any()) {
withModalProgress(ModalTaskOwner.component(debuggerKindComboBox), "Downloading debugger", TaskCancellation.cancellable()) {
downloadDebugger()
}
@ -96,7 +97,7 @@ class ZigDebuggerToolchainConfigurableUi : ZigDebuggerUiComponent {
}
.applyToComponent {
whenItemSelected(null) {
zigCoroutineScope.launchWithEDT {
zigCoroutineScope.launchWithEDT(ModalityState.any()) {
this@ZigDebuggerToolchainConfigurableUi.update()
}
}
@ -111,7 +112,7 @@ class ZigDebuggerToolchainConfigurableUi : ZigDebuggerUiComponent {
cell(useClion)
}
}
zigCoroutineScope.launchWithEDT {
zigCoroutineScope.launchWithEDT(ModalityState.any()) {
update()
}
}

View file

@ -29,6 +29,7 @@ import com.intellij.ide.util.projectWizard.ModuleBuilder
import com.intellij.ide.util.projectWizard.ModuleWizardStep
import com.intellij.ide.util.projectWizard.WizardContext
import com.intellij.openapi.Disposable
import com.intellij.openapi.application.ModalityState
import com.intellij.openapi.module.ModuleType
import com.intellij.openapi.roots.ModifiableRootModel
import com.intellij.openapi.util.Disposer
@ -58,7 +59,7 @@ class ZigModuleBuilder: ModuleBuilder() {
val root = contentEntry.file ?: return
val config = configurationData ?: return
config.generateProject(this, rootModel.project, root, forceGitignore)
withEDTContext {
withEDTContext(ModalityState.defaultModalityState()) {
root.refresh(false, true)
}
}

View file

@ -95,7 +95,7 @@ class ZigProjectSettingsPanel(private val holder: ZigProjectConfigurationProvide
}
private fun dispatchAutodetect(force: Boolean) {
project.zigCoroutineScope.launchWithEDT {
project.zigCoroutineScope.launchWithEDT(ModalityState.any()) {
withModalProgress(ModalTaskOwner.component(pathToToolchain), "Detecting Zig...", TaskCancellation.cancellable()) {
autodetect(force)
}

View file

@ -27,6 +27,7 @@ import com.falsepattern.zigbrains.project.steps.discovery.ZigStepDiscoveryListen
import com.falsepattern.zigbrains.shared.coroutine.withEDTContext
import com.falsepattern.zigbrains.shared.zigCoroutineScope
import com.intellij.openapi.Disposable
import com.intellij.openapi.application.ModalityState
import com.intellij.openapi.components.Service
import com.intellij.openapi.components.service
import com.intellij.openapi.diagnostic.Logger
@ -124,7 +125,7 @@ class ZigStepDiscoveryService(private val project: Project) {
}
private suspend fun dispatchReload() {
withEDTContext {
withEDTContext(ModalityState.defaultModalityState()) {
FileDocumentManager.getInstance().saveAllDocuments()
}
doReload()

View file

@ -39,7 +39,7 @@ inline fun <T> runModalOrBlocking(taskOwnerFactory: () -> ModalTaskOwner, titleF
}
}
suspend inline fun <T> withEDTContext(state: ModalityState = ModalityState.defaultModalityState(), noinline block: suspend CoroutineScope.() -> T): T {
suspend inline fun <T> withEDTContext(state: ModalityState, noinline block: suspend CoroutineScope.() -> T): T {
return withContext(Dispatchers.EDT + state.asContextElement(), block = block)
}
@ -49,10 +49,10 @@ suspend inline fun <T> withCurrentEDTModalityContext(noinline block: suspend Cor
}
}
suspend inline fun <T> runInterruptibleEDT(state: ModalityState = ModalityState.defaultModalityState(), noinline targetAction: () -> T): T {
suspend inline fun <T> runInterruptibleEDT(state: ModalityState, noinline targetAction: () -> T): T {
return runInterruptible(Dispatchers.EDT + state.asContextElement(), block = targetAction)
}
fun CoroutineScope.launchWithEDT(state: ModalityState = ModalityState.defaultModalityState(), block: suspend CoroutineScope.() -> Unit): Job {
fun CoroutineScope.launchWithEDT(state: ModalityState, block: suspend CoroutineScope.() -> Unit): Job {
return launch(Dispatchers.EDT + state.asContextElement(), block = block)
}

View file

@ -279,7 +279,7 @@ class ZLSSettingsPanel(private val project: Project) : ZigProjectConfigurationPr
}
private fun dispatchAutodetect(force: Boolean) {
project.zigCoroutineScope.launchWithEDT {
project.zigCoroutineScope.launchWithEDT(ModalityState.any()) {
withModalProgress(ModalTaskOwner.component(zlsPath), "Detecting ZLS...", TaskCancellation.cancellable()) {
autodetect(force)
}