Skip to content

scala.sys.process.ProcessImpl.SimpleProcess.destroy() doesn't clean up the output threads nicely #6488

@scabug

Description

@scabug

SimpleProcess doesn't cleanup its output threads when destroying the underlying Java thread:

sys.process.Process("sleep 10").run(sys.process.ProcessLogger { 
  (s: String) => println(s)
}).destroy

leads to

[error] (Thread-72) java.io.IOException: Stream closed
s: Unit = ()
[error] (Thread-73) java.io.IOException: Bad file descriptor

scala> java.io.IOException: Stream closed
	at java.io.BufferedInputStream.getBufIfOpen(BufferedInputStream.java:145)
	at java.io.BufferedInputStream.read(BufferedInputStream.java:308)
	at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264)
	at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)
	at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)
	at java.io.InputStreamReader.read(InputStreamReader.java:167)
	at java.io.BufferedReader.fill(BufferedReader.java:136)
	at java.io.BufferedReader.readLine(BufferedReader.java:299)
	at java.io.BufferedReader.readLine(BufferedReader.java:362)
	at scala.sys.process.BasicIO$$anonfun$processFully$1$$anonfun$apply$6.apply(BasicIO.scala:164)
	at scala.sys.process.BasicIO$$anonfun$processFully$1$$anonfun$apply$6.apply(BasicIO.scala:164)
	at scala.sys.process.BasicIO$.readFully$1(BasicIO.scala:173)
	at scala.sys.process.BasicIO$.processLinesFully(BasicIO.scala:179)
	at scala.sys.process.BasicIO$$anonfun$processFully$1.apply(BasicIO.scala:164)
	at scala.sys.process.BasicIO$$anonfun$processFully$1.apply(BasicIO.scala:162)
	at scala.sys.process.ProcessBuilderImpl$Simple$$anonfun$3.apply$mcV$sp(ProcessBuilderImpl.scala:73)
	at scala.sys.process.ProcessImpl$Spawn$$anon$1.run(ProcessImpl.scala:22)
java.io.IOException: Bad file descriptor
	at java.io.FileInputStream.readBytes(Native Method)
	at java.io.FileInputStream.read(FileInputStream.java:220)
	at java.lang.UNIXProcess$DeferredCloseInputStream.read(UNIXProcess.java:227)
	at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264)
	at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)
	at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)
	at java.io.InputStreamReader.read(InputStreamReader.java:167)
	at java.io.BufferedReader.fill(BufferedReader.java:136)
	at java.io.BufferedReader.readLine(BufferedReader.java:299)
	at java.io.BufferedReader.readLine(BufferedReader.java:362)
	at scala.sys.process.BasicIO$$anonfun$processFully$1$$anonfun$apply$6.apply(BasicIO.scala:164)
	at scala.sys.process.BasicIO$$anonfun$processFully$1$$anonfun$apply$6.apply(BasicIO.scala:164)
	at scala.sys.process.BasicIO$.readFully$1(BasicIO.scala:173)
	at scala.sys.process.BasicIO$.processLinesFully(BasicIO.scala:179)
	at scala.sys.process.BasicIO$$anonfun$processFully$1.apply(BasicIO.scala:164)
	at scala.sys.process.BasicIO$$anonfun$processFully$1.apply(BasicIO.scala:162)
	at scala.sys.process.ProcessBuilderImpl$Simple$$anonfun$4.apply$mcV$sp(ProcessBuilderImpl.scala:76)
	at scala.sys.process.ProcessImpl$Spawn$$anon$1.run(ProcessImpl.scala:22)

In our code which has long running processes, we are seeing java.io.IOException: Bad file descriptor being thrown when we destroy the process. The above only seems to get that (and the Stream Closed) if we destroy as soon as we create.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions