NIO Socket.read() may not respect the socket timeout

Alexei Olkhovskii alexei.olkhovskii at servicenow.com
Tue May 27 22:50:36 UTC 2025


Hello,

We’ve ran into a corner-case issue with socket read(). In short, it doesn’t honor socket timeout when trying to acquire the read lock:
https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/sun/nio/ch/NioSocketImpl.java#L336

  readLock.lock();

In our case one thread obtained a database connection and got stuck in read() (we think because of a StackOverflow). The thread was holding the readLock. Our connection pool gave the connection to another thread which tried to clean it up. While doing that, it attempted to drain the socket with 3 millisecond timeout:

  socket.setSoTimeout(3);        // supposed to prevent blocking
  InputStream is = socket.getInputStream();
  while (is.read() != -1) {      // blocked forever because of the JDK lock
         //read byte
  }

We think that instead of unconditional locking the method should use its timed version like accept() is doing:
https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/sun/nio/ch/NioSocketImpl.java#L715

Note: the fix may also be applied to connect().

The test case is attached.

--
Regards, Alexei

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/nio-dev/attachments/20250527/36333fae/attachment.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: SocketTimeoutNotRespected.java
Type: application/octet-stream
Size: 3823 bytes
Desc: SocketTimeoutNotRespected.java
URL: <https://mail.openjdk.org/pipermail/nio-dev/attachments/20250527/36333fae/SocketTimeoutNotRespected.java>


More information about the nio-dev mailing list