NIO Socket.read() may not respect the socket timeout
Alexei Olkhovskii
alexei.olkhovskii at servicenow.com
Thu May 29 21:20:19 UTC 2025
> It's hard to know if there if there is a case where concurrent reads from the same TCP/socket stream make sense ... If there is a protocol where it's possible to do something sensible when reading subsets of bytes, and with different timeouts, or code handling SocketTimeoutException then maybe your point could be looked ...
Yes, a conscious design involving concurrent Socket use would be a strange thing, no argument there. Also, your point about connect() makes total sense.
Going back to read(), what would be the way out of the situation for the API users? The app has detected stale data in the socket buffer and tries to clean things up. It isn’t aware the other reader is still alive and calls JDBC abort(). The JDBC spec allows Connection sharing, the driver isn’t even obliged to check for concurrency. Sure, it is doing a questionable read(), but while taking the timeout precautions.
In this situation NIO is the only player aware of the other reader. Which brings us to the choice: try to eliminate the reason the other player is holding the lock (which sounds like an uphill battle) or behave transparently to the lock presence: wait for the timeout interval and return -1 like if there was no data. Besides, the lock is an internal library mechanism whose existence has only surfaced accidently.
>From the API user standpoint, the second option sounds simpler to handle. Not saying we ever will but should someone want to code around a hund read, that’d bring a lot of complexity.
> I'd prefer not use that to justify doing something to help a workaround when it does happen.
Please note that we’d not make the situation worse than today, should somebody attempt to call read() concurrently. The logical difference would be “the call returned no data because **there is** no data” vs “the call returned no data because somebody else is reading it and we’ve timed out” (as opposed to today’s “wait for an uncertain interval till the other party has finished their read”).
--
Regards, Alexei
From: Alan Bateman <alan.bateman at oracle.com>
Date: Thursday, May 29, 2025 at 10:40
To: Alexei Olkhovskii <alexei.olkhovskii at servicenow.com>, nio-dev at openjdk.org <nio-dev at openjdk.org>
Subject: Re: NIO Socket.read() may not respect the socket timeout
[External Emai
________________________________
On 28/05/2025 20:46, Alexei Olkhovskii wrote:
> This may be an issue with the reserved stack area. There was work done in JDK 9 via JEP 270 [1] but I think it needs to be looked at again.
Perhaps https://bugs.openjdk.org/browse/JDK-8318888<https://bugs.openjdk.org/browse/JDK-8318888> is also relevant.
Yes, there are a few reports of issues when continuing after SOE.
But regardless of the reason the other thread is holding the lock, don’t you think the socket timeout should be respected for read(), connect(), etc?
The connect method is only allowed once. It would be strange to create an unconnected Socket and then attempt to have 2 threads invoke connect. The second attempt must fail with SocketException (it will be "Connection in progress" or "Socket closed"). You are right that the second attempt will block, maybe beyond the connect timeout it specifies, before it throws the SocketException. I don't think this is worth spending time on as there is impossible for the second connect to succeed.
It's hard to know if there if there is a case where concurrent reads from the same TCP/socket stream make sense. At one point it was possible to have a Socket to a UDP socket but that mis-feature is deprecated a long time ago. If several threads are reading from the same stream then it requires coordination at a higher level, something that understands the protocol, meaning the lock contention will be further up the stack. If there is a protocol where it's possible to do something sensible when reading subsets of bytes, and with different timeouts, or code handling SocketTimeoutException then maybe your point could be looked. For now, I think the issue here is the "lock corruption" and we need to understand this a bit more. I'd prefer not use that to justify doing something to help a workaround when it does happen.
-Alan
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/nio-dev/attachments/20250529/8199fd71/attachment-0001.htm>
More information about the nio-dev
mailing list