diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6c2cc30a4..8ca875355 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -186,6 +186,7 @@ jobs: shell: bash run: | # test building sbtn on Windows + sbt "commandProj/testOnly xsbt.IPCSpec" sbt "-Dsbt.io.virtual=false" nativeImage # test launcher script echo build using JDK 8, test using JDK 8, on Windows diff --git a/main-command/src/main/scala/xsbt/IPC.scala b/main-command/src/main/scala/xsbt/IPC.scala index 9c353613d..b5ce13ee5 100644 --- a/main-command/src/main/scala/xsbt/IPC.scala +++ b/main-command/src/main/scala/xsbt/IPC.scala @@ -17,6 +17,7 @@ object IPC { private val portMin = 1025 private val portMax = 65536 private val loopback = InetAddress.getByName(null) + private[xsbt] val socketBacklog = 50 // 50 is the default backlog size for the java.net.Socket def client[T](port: Int)(f: IPC => T): T = ipc(new Socket(loopback, port))(f) @@ -34,7 +35,7 @@ object IPC { def createServer(attempts: Int): ServerSocket = if (attempts > 0) { - try new ServerSocket(nextPort, 1, loopback) + try new ServerSocket(nextPort, socketBacklog, loopback) catch { case NonFatal(_) => createServer(attempts - 1) } } else sys.error("Could not connect to socket: maximum attempts exceeded") diff --git a/main-command/src/test/scala/xsbt/IPCSpec.scala b/main-command/src/test/scala/xsbt/IPCSpec.scala new file mode 100644 index 000000000..dfeb1dc4f --- /dev/null +++ b/main-command/src/test/scala/xsbt/IPCSpec.scala @@ -0,0 +1,23 @@ +/* + * sbt + * Copyright 2011 - 2018, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under Apache License 2.0 (see LICENSE) + */ + +package xsbt + +import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.matchers.should.Matchers._ + +class IPCSpec extends AnyFlatSpec { + "server" should "allow same number of connections as determined in socket backlog" in { + noException should be thrownBy { + val server = IPC.unmanagedServer + (1 until IPC.socketBacklog + 1).foreach { _ => + IPC.client(server.port)(identity) + } + server.close() + } + } +}