AsynchronousSocketChannel still throws unspecified exception

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.

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

5. 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