RFR: 8280113: (dc) DatagramSocket.receive does not always throw when the channel is closed

Alan Bateman alanb at openjdk.org
Tue Feb 21 07:26:28 UTC 2023


On Tue, 21 Feb 2023 07:18:02 GMT, Jaikiran Pai <jpai at openjdk.org> wrote:

>> This is an issue with the async close of a DatagramChannel when a thread is blocked in its adaptor's receive method and the underlying socket is non-blocking.  The async close causes poll to wakeup and the underlying receive to return 0 so it can't be distinguished from a receive of a zero-length datagram. The channel state needs to be checked to distinguish the two cases so that AsynchronousCloseException can be thrown if the channel has been closed. The bug goes back to JDK 14 when caching of sockaddr structured was introduced.
>> 
>> The test case creates the conditions to exercise the case for both the timed and untimed receive. The bug report is the timed case, which receives two datagrams before attempting a timed receive. The harder case to test is the untimed case so the test uses a virtual thread to force the underlying socket to be non-blocking.
>
> test/jdk/java/nio/channels/DatagramChannel/AdaptorAsyncCloseAfterReceive.java line 83:
> 
>> 81:             // schedule socket to be closed while main thead blocked in receive
>> 82:             DatagramSocket s = dc.socket();
>> 83:             Future<?> future = scheduler.schedule(() -> s.close(), 1, TimeUnit.SECONDS);
> 
> Hello Alan, would it be a good idea to schedule this `close()` as late as possible, just before the call to `s.receive(p)`? On heavily loaded systems, that would then prevent potential intermittent failures where this `s.close()` task could get fired before the control reaches `s.setSoTimeout(timeout)` and the `setSoTimeout(...)` thus would fail with a `SocketException`.

That's a good point, it should be after the setSoTimeout to avoid an intermittent failure on a very slow/overloaded test machine.

-------------

PR: https://git.openjdk.org/jdk/pull/12674


More information about the nio-dev mailing list