[rdct] IJPL-198605: Dispose the previous session inplace if the call is from EDT

Previously dispose has been called from the `launch` to the `EDT` from `IO`. That led to the scenarios where the old session hasn't been disposed, when the new one has been already initialized and running.

In total, that created a data race


(cherry picked from commit aae4db92851bf5e917fe21ac5f9a209259dbe017)

IJ-MR-174360

GitOrigin-RevId: dd33264e8ebc22e6654c22203bb1f851a5d33662
This commit is contained in:
Sergei Kharitontcev-Beglov
2025-08-28 12:36:38 +02:00
committed by intellij-monorepo-bot
parent b001c8d9cc
commit 9089f5065e

View File

@@ -1,4 +1,4 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// 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.client
import com.intellij.codeWithMe.ClientId
@@ -10,6 +10,7 @@ import com.intellij.openapi.diagnostic.logger
import com.intellij.openapi.progress.ProcessCanceledException
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Disposer
import com.intellij.util.ui.EDT
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
@@ -140,8 +141,11 @@ open class ClientSessionsManager<T : ClientSession>(private val scope: Coroutine
// it may happen that a new session of a client is handled earlier than its previous session is disposed and removed.
// It happens because `disposable` of the prev session is disposed with some delay in WireStorage.terminateWire (it's scheduled with launch {}).
LOG.warn("Session $oldSession with such clientId $clientId is already registered and will be replaced with $session")
scope.launch(Dispatchers.EDT + ModalityState.any().asContextElement()) {
writeIntentReadAction {
if (EDT.isCurrentThreadEdt()) {
Disposer.dispose(oldSession)
}
else {
scope.launch(Dispatchers.EDT + ModalityState.any().asContextElement()) {
Disposer.dispose(oldSession)
}
}