From b337f3d9acc979dec2185bb50665a20a940b2d55 Mon Sep 17 00:00:00 2001 From: James Roper Date: Fri, 1 Nov 2013 17:20:01 +1100 Subject: [PATCH] Flush ObjectOutputStreams after construction This protects against deadlocks between the writing and reading end, since the ObjectOutputStream constructor writes a header, but does not flush, and the ObjectInputStream constructor reads the header, and blocks until it's read. --- main/actions/src/main/scala/sbt/ForkTests.scala | 2 ++ testing/agent/src/main/java/sbt/ForkMain.java | 2 ++ 2 files changed, 4 insertions(+) diff --git a/main/actions/src/main/scala/sbt/ForkTests.scala b/main/actions/src/main/scala/sbt/ForkTests.scala index 981c714cf..b9186b1fe 100755 --- a/main/actions/src/main/scala/sbt/ForkTests.scala +++ b/main/actions/src/main/scala/sbt/ForkTests.scala @@ -49,6 +49,8 @@ private[sbt] object ForkTests case _: java.net.SocketException => return } val os = new ObjectOutputStream(socket.getOutputStream) + // Must flush the header that the constructor writes, otherwise the ObjectInputStream on the other end may block indefinitely + os.flush() val is = new ObjectInputStream(socket.getInputStream) try { diff --git a/testing/agent/src/main/java/sbt/ForkMain.java b/testing/agent/src/main/java/sbt/ForkMain.java index c54d177da..a494adbc4 100755 --- a/testing/agent/src/main/java/sbt/ForkMain.java +++ b/testing/agent/src/main/java/sbt/ForkMain.java @@ -92,6 +92,8 @@ public class ForkMain { Socket socket = new Socket(InetAddress.getByName(null), Integer.valueOf(args[0])); final ObjectInputStream is = new ObjectInputStream(socket.getInputStream()); final ObjectOutputStream os = new ObjectOutputStream(socket.getOutputStream()); + // Must flush the header that the constructor writes, otherwise the ObjectInputStream on the other end may block indefinitely + os.flush(); try { try { new Run().run(is, os);