mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-03-22 15:19:59 +07:00
[python] PY-85433: Survive IOException thrown by read.
While closing remote stream should lead to `EOF` (`-1`), `read` might still throw `IOException`. This is documented by the `read` contract, and we face it when underlying stream gets closed i.e: one thread was blocked by `read` and another one called `close`. (cherry picked from commit 2c49be37333a794c6ed1f5ce4ad3d8d2f29b93fa) IJ-MR-181675 GitOrigin-RevId: f3f40e8edbc0caa2450b297ae278b37a754a5f49
This commit is contained in:
committed by
intellij-monorepo-bot
parent
53e078ff30
commit
e11a58046b
@@ -1,6 +1,7 @@
|
||||
// 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.python.community.execService.impl
|
||||
|
||||
import com.intellij.openapi.diagnostic.fileLogger
|
||||
import com.intellij.platform.eel.provider.utils.EelProcessExecutionResult
|
||||
import com.intellij.python.community.execService.ProcessEvent
|
||||
import com.intellij.python.community.execService.ProcessEvent.OutputType
|
||||
@@ -12,11 +13,14 @@ import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import kotlinx.coroutines.flow.FlowCollector
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import java.io.IOException
|
||||
|
||||
/**
|
||||
* Awaits of process result and reports its stdout/stderr as a progress.
|
||||
*/
|
||||
internal suspend fun Process.awaitWithReporting(progressListener: FlowCollector<ProcessEvent.ProcessOutput>?): EelProcessExecutionResult =
|
||||
@ApiStatus.Internal
|
||||
suspend fun Process.awaitWithReporting(progressListener: FlowCollector<ProcessEvent.ProcessOutput>?): EelProcessExecutionResult =
|
||||
coroutineScope {
|
||||
val stdout = async { report(STDOUT, progressListener) }
|
||||
val stderr = async { report(STDERR, progressListener) }
|
||||
@@ -36,7 +40,13 @@ private suspend fun Process.report(outputType: OutputType, to: FlowCollector<Pro
|
||||
|
||||
val currentLine = StringBuilder()
|
||||
while (true) {
|
||||
val char = reader.read()
|
||||
val char = try {
|
||||
reader.read() // Read might throw IOException if steam is closed explicitly in JVM, see test with the same commit
|
||||
}
|
||||
catch (e: IOException) {
|
||||
logger.warn("Error reading from process", e)
|
||||
-1
|
||||
}
|
||||
if (char == -1) break // EOF
|
||||
|
||||
when (val c = char.toChar()) {
|
||||
@@ -71,4 +81,6 @@ private suspend fun Process.report(outputType: OutputType, to: FlowCollector<Pro
|
||||
result.append(currentLine)
|
||||
}
|
||||
return@withContext result.toString().encodeToByteArray()
|
||||
}
|
||||
}
|
||||
|
||||
private val logger = fileLogger()
|
||||
Reference in New Issue
Block a user