AsynchronousSocketChannel still throws unspecified exception (original) (raw)

cowwoc cowwoc at bbs.darktech.org
Wed Jul 13 10:02:10 PDT 2011


cowwoc wrote:

On 13/07/2011 11:51 AM, Alan Bateman wrote:

3. When the user passes a timeout <= 0, readImpl() return any available bytes (without issuing a read on the underlying file/socket handle). If no bytes are available, it will return 0 bytes read.

Now, how does this compare to the actual implementation? What is the current behavior? As it stands, if the timeout is <= 0 then it means there isn't any_ _timeout. If there are available bytes or we're at end of stream then_ _the read operation will complete immediately (meaning the completion_ _handler will be invoked immediately). Otherwise the read will only_ _complete when bytes arrive, the peer closes the connection, or some_ _error occurs. This is how it is both specified and implemented._ _So where we mostly differ is at 3 where I think you are arguing that_ _<= 0 is a read that is guaranteed to complete immediately. We don't_ _have today and would require a bit of consideration to ensure that (a)_ _it is actually needed, and (b) what the API would be._ _Okay, but this contradicts our original discussion and how j.u.c_ _works (which we're trying to be consistent with). I'll give you a simple_ _example. If I invoke CountDownLatch.await(0, TimeUnit.MILLISECONDS) the_ _specification reads "If the current count is zero then this method_ _returns immediately." So first of all we've established that a timeout_ _of zero should never block._ _The next example demonstrates how a timeout of zero can be used to_ _poll a value. If I invoke ReentrantLock.tryLock(0,_ _TimeUnit.MILLISECONDS) it tries acquiring the lock without waiting. If_ _the lock is not immediately available, it returns false. If it is_ _immediately available, it establishes the lock and returns true. That's_ _my interpretation based on_ _http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/locks/ReentrantLock.html#tryLock%28%29_ _'s discussion of "if you want to honor the fairness setting for this_ _lock"._ _Reading the "available bytes" requires reading from the socket so a_ _read will be initiated. If it completes before the timeout has elapsed_ _then the timer will be cancelled._ _I understand but I expect this to work similar to_ _ReentrantLock.tryLock(0, TimeUnit). If available() >= 0 then it should return all available bytes immediately regardless of what the timeout value is. I believe you simply need to invoke available() before beginning a read. If it returns a non-zero value, disable the timeout and read forever (the OS guarantees this should return instantaneously). Gili

As for why we need this, quoting http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7063249:

  1. Consistency with java.util.concurrent
  2. Common sense (waiting 0 means not waiting at all)
  3. It makes waits composable:

void composite(timeLimit) { ... step1(timeLimit); ... step2(timeLimit - elapsed); } which otherwise can surprisingly misbehave if timeLimit - elapsed happens to be 0.

  1. Without this change, there is no way to ask a channel to return existing data without waiting.

  2. Without this change, there is no way of checking whether the channel is in an "error state" without reading at least one byte (in case it is not in the error state).

Gili

-- View this message in context: http://nio-dev.3157472.n2.nabble.com/AsynchronousSocketChannel-still-throws-unspecified-exception-tp6471557p6579825.html Sent from the nio-dev mailing list archive at Nabble.com.



More information about the nio-dev mailing list