Reputation: 11
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");
...
}
Upvotes: 1
Views: 1312
Reputation: 310850
'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.
Upvotes: 3