AsynchronousByteCharChannel and Timeouts
Alan Bateman
Alan.Bateman at Sun.COM
Thu Aug 6 02:07:27 PDT 2009
Gili wrote:
> :
> Okay. I agree with everything you wrote except for the earlier post about
> how it should be possible to implement read-with-timeout in terms of
> read-forever.
Right, this is where we differ because AsynchronousSocketChannel does
not require the implementation to have a mechanism to cancel the
underlying I/O operation.
> For the win32 comport API at least this doesn't seem to be
> possible. How does it work for sockets?
>
It's done using overlapped I/O with WSARecv/WSASend. A completion port
is used to receive the notifications when the I/O operations complete.
We don't make use of I/O cancellation (Windows Vista did bring a new
Win32 call to cancel specific I/O operations but it doesn't provide the
guarantees that we require and we don't use it).
If it were implemented as blocking sockets then the same issue would
arise (from the Win32 docs: "If a send or receive operation times out on
a socket, the socket state is indeterminate, and should not be used; TCP
sockets in this state have a potential for data loss, since the
operation could be canceled at the same moment the operation was to be
completed.")
> If you start a read for 10 bytes and a Timer tells you about a timeout after
> you only read 5 bytes are you saying you can tell the underlying OS to stop
> reading but also give you whatever data it already read? As I mentioned
> before, the OS lets me stop ongoing reads for serial ports but then it will
> queue any read data and I can only get at it if I try to read() again.
>
A read operation is not required to fill the buffer so if you initiate a
read up to 10 bytes then it is normal have the read to complete having
read less than 10 bytes.
For the case that the timer expires at just around the time that 5 bytes
have been read into your buffer then the best solution is to have the
I/O operation complete (successfully) and the buffer position moved on
by 5 bytes. If you are saying that this is not feasible (because the
underlying read returns 0) then are those 5 bytes lost? If this were a
stream/socket then this data loss would be a disaster if the application
were to read bytes after the timeout and data loss. For a serial
connection (we are talking RS232 or descendants, right?) then it's not
too bad as there will likely be a high level protocol to detect errors.
-Alan.
More information about the nio-discuss
mailing list