1

I occasionally have run into a case where SocketChannel.read() blocks on a non-blocking channel (JDK 1.6 variants on RH6). My reading of the spec says that this should never happen. After adding a large timeout to the socket (which I don't think should ever really be necessary...), I see the following: java.io.IOException: Connection timed out at sun.nio.ch.FileDispatcherImpl.read0(Native method) ... at sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:380) ... Looking at the source, this is simply calling read(), which presumably should not block on a file descriptor with O_NONBLOCK set.

(This may be similar to: SocketChannel.read() blocks indefinitely, however in my case the channel has definitely been configured as non-blocking, and synchronization really shouldn't matter here IMHO as the call shouldn't block irrespective of any other considerations.)

I'm aware that a non-blocking read() might block due to - say - paging, but my socket timeout is set for several minutes, so paging can't realistically be the culprit.

Any ideas?

Setup code is:

public void addConnection(SocketChannel channel) throws SocketException {
    channel.socket().setTcpNoDelay(true);
    channel.socket().setReceiveBufferSize(defReceiveBufferSize);
    channel.socket().setSendBufferSize(defSendBufferSize);
    channel.socket().setSoTimeout(defSocketReadTimeout);
    try {
        channel.configureBlocking(false);
    } catch (IOException ioe) {
        Log.logErrorWarning(ioe);
        throw new RuntimeException("Unable to configure non-blocking socket");
   ...
}
  • 1
    Can you post the code setting up and using `SocketChannel`? – phflack Nov 01 '17 at 19:49
  • The complete code is too involved to post, unfortunately. I have added the relevant setup code. Usage is just `numRead = socketChannelInstance.read(buffer)`. – user8870183 Nov 01 '17 at 20:07

1 Answers1

3

'Connection timed out' means a network error, not a read timeout.

There is no evidence here that the read actually blocked. The network error was already sitting there, waiting for an I/O operation to report it to. Your read() returned immediately by throwing this exception.

It doesn't make any sense to set a read timeout on a non-blocking socket channel.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • Good catch. I was looking at the "timed out" and presuming it came from a read() timeout, but it's likely a broken connection. Test code shows that `socketChannelInstance.read(buffer)` ignores the socket timeout anyway. I have some evidence of delays in operations. I'll instrument a bit more to get solid data on timing. Good lead. – user8870183 Nov 02 '17 at 01:45