8198562: (ch) Separate blocking and non-blocking code paths (part 1)

Alan Bateman Alan.Bateman at oracle.com
Thu Feb 22 19:08:41 UTC 2018

I mentioned in a thread here earlier this month that I have a number of 
patches to reduce the complexity and overhead of supporting async close 
and interrupt in the selectable channel implementations.  All combined, 
there are a lot of changes but are easy to split into a series of 
smaller patches that are easier to test and review.

The patch here changes the SocketChannel and ServerSocketChannel 
implementations so that channels configured non-blocking don't set the 
hook for Thread.interrupt or don't track the threads potentially 
blocking in I/O operations. The blocking case is improved too by 
reducing, at least for the SocketChannel implementation, the locking 
around the blocking calls. All the locking is consistent now, something 
that will be clearer once the changes to DatagramChannel and the Pipe.* 
implementations are discussed.

Simplification of the read/write/accept/connect/finishConnect methods 
means that the implCloseSelectableChannel has to handle both the 
blocking and non-blocking cases but it's not too complicated.

The socket adaptors have also changed so that they do timed operations 
(Socket setSoTimeout and friends) with the channel configured blocking. 
This it to avoid an explosion of scenarios (and complexity) that arises 
when trying to be both blocking and non-blocking at the same time.

In terms of compatibility, there are two behavioral changes:

1. If a thread's interrupt status is set and it invokes an I/O method on 
a channel configured non-blocking then the channel will not be closed. 
The original specification was vague on this point as it focused on 
threads blocking in I/O operations. Several people have complained 
bitterly over the years about the existing behavior so they will welcome 
this change. I haven't found anything yet that depends on long standing 
behavior but we will need to track this in a CSR anyway.

2. configureBlocking will now block if there are pending I/O operations. 
The spec has always stated that it may block so it should not be a 
surprise but there may be some cases where code attempts to change a 
channel to non-blocking while another thread is doing on a blocking I/O 
operation on the channel. This method now coordinates with channel 
closing, something that has never been right in the implementation.

The webrev with the patch is here:


More information about the nio-dev mailing list