From 0d41593da9b7fed69b25a15bb2a0ab7523295bd1 Mon Sep 17 00:00:00 2001 From: Arman Bilge Date: Tue, 30 Aug 2022 02:19:26 +0000 Subject: [PATCH 1/3] reproduce blocked read --- .../test/scala/epollcat/tcp/TcpSuite.scala | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/tests/shared/src/test/scala/epollcat/tcp/TcpSuite.scala b/tests/shared/src/test/scala/epollcat/tcp/TcpSuite.scala index 3d878ac..5a0b8bc 100644 --- a/tests/shared/src/test/scala/epollcat/tcp/TcpSuite.scala +++ b/tests/shared/src/test/scala/epollcat/tcp/TcpSuite.scala @@ -229,4 +229,23 @@ class TcpSuite extends EpollcatSuite { .intercept[ClosedChannelException] } + test("read does not block".only) { + IOServerSocketChannel.open.use { server => + IOSocketChannel.open.use { clientCh => + for { + _ <- server.bind(new InetSocketAddress(0)) + addr <- server.localAddress + _ <- clientCh.connect(addr) + _ <- clientCh.write(ByteBuffer.wrap("Hello!".getBytes)) + _ <- server.accept.use { serverCh => + for { + bb <- IO(ByteBuffer.allocate(8192)) + _ <- serverCh.read(bb) + } yield () + } + } yield () + } + } + } + } From 38bc990312177a48f3490878e50d720773712083 Mon Sep 17 00:00:00 2001 From: Arman Bilge Date: Tue, 30 Aug 2022 02:33:56 +0000 Subject: [PATCH 2/3] Use `accept4` with `SOCK_NONBLOCK` flag --- .../epollcat/internal/net/EpollAsyncServerSocketChannel.scala | 4 ++-- .../scala/epollcat/internal/net/EpollAsyncSocketChannel.scala | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/net/src/main/scala/epollcat/internal/net/EpollAsyncServerSocketChannel.scala b/net/src/main/scala/epollcat/internal/net/EpollAsyncServerSocketChannel.scala index 416b2d6..ae58145 100644 --- a/net/src/main/scala/epollcat/internal/net/EpollAsyncServerSocketChannel.scala +++ b/net/src/main/scala/epollcat/internal/net/EpollAsyncServerSocketChannel.scala @@ -125,7 +125,7 @@ final class EpollAsyncServerSocketChannel private (fd: Int) handler: CompletionHandler[AsynchronousSocketChannel, _ >: A] ): Unit = { if (readReady) { - val clientFd = syssocket.accept(fd, null, null) + val clientFd = syssocket.accept4(fd, null, null, EpollAsyncSocketChannel.SOCK_NONBLOCK) if (clientFd == -1) { if (errno.errno == posix.errno.EAGAIN || errno.errno == posix.errno.EWOULDBLOCK) { readReady = false @@ -183,5 +183,5 @@ object EpollAsyncServerSocketChannel { @extern @nowarn private[net] object syssocket { - def accept(sockfd: CInt, addr: Ptr[Byte], addrlen: Ptr[Byte]): CInt = extern + def accept4(sockfd: CInt, addr: Ptr[Byte], addrlen: Ptr[Byte], flags: CInt): CInt = extern } diff --git a/net/src/main/scala/epollcat/internal/net/EpollAsyncSocketChannel.scala b/net/src/main/scala/epollcat/internal/net/EpollAsyncSocketChannel.scala index 45bf226..0667082 100644 --- a/net/src/main/scala/epollcat/internal/net/EpollAsyncSocketChannel.scala +++ b/net/src/main/scala/epollcat/internal/net/EpollAsyncSocketChannel.scala @@ -351,7 +351,7 @@ final class EpollAsyncSocketChannel private (fd: Int) extends AsynchronousSocket } object EpollAsyncSocketChannel { - private final val SOCK_NONBLOCK = 2048 + final val SOCK_NONBLOCK = 2048 def open(): EpollAsyncSocketChannel = { val fd = posix From 9a084b26b2ba6f319a5463f079744c5933bc261c Mon Sep 17 00:00:00 2001 From: Arman Bilge Date: Tue, 30 Aug 2022 02:35:11 +0000 Subject: [PATCH 3/3] More precise test name --- tests/shared/src/test/scala/epollcat/tcp/TcpSuite.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/shared/src/test/scala/epollcat/tcp/TcpSuite.scala b/tests/shared/src/test/scala/epollcat/tcp/TcpSuite.scala index 5a0b8bc..df4ddfc 100644 --- a/tests/shared/src/test/scala/epollcat/tcp/TcpSuite.scala +++ b/tests/shared/src/test/scala/epollcat/tcp/TcpSuite.scala @@ -229,7 +229,7 @@ class TcpSuite extends EpollcatSuite { .intercept[ClosedChannelException] } - test("read does not block".only) { + test("server socket read does not block") { IOServerSocketChannel.open.use { server => IOSocketChannel.open.use { clientCh => for {