8201474: (so) Socket adaptor connect(InetAddress, timeout) succeeds when connection fails

Alan Bateman Alan.Bateman at oracle.com
Tue Apr 17 06:50:08 UTC 2018


On 17/04/2018 06:26, Hamlin Li wrote:
>
> :
>
> Yes, you're right too.
> But, the root cause for "pollConnected changed the channel state to 
> ST_CONNECTED" is that pollConnect only check whether return result of 
> Net.poll(...) > 0, it does not check whether it is/includes POLLERR, 
> POLLHUP, POLLNVAL, so endFinishConnect is passed true for parameter 
> completed when events is/includes POLLERR, POLLHUP, POLLNVAL, this 
> will cause "state = ST_CONNECTED;" in endFinishConnect.
> To fix this, completed should be calculated separately from polled, so 
> when POLLERR, POLLHUP, POLLNVAL is included in result of Net.poll(), 
> polled == true, but completed == false, endFinishConnect will not set 
> "state = ST_CONNECTED;". In this way, there is no need to treat 
> pollConnect differently from other pollXXX, and pass false explicitly 
> to completed parameter of endFinishConnect.
> Hope I have explained clearly.
It's important that the pollXXX methods return true whenever any events, 
including POLLERR or POLLHUP, are polled. Consider the following:

Socket s = sc.socket();
s.setSoTimeout(10*1000);
int n = s.getInputStream().read(b);

Assuming no bytes are available, this will block in poll. Now suppose 
the connection is terminated, say RST. In that case, you should see a 
POLLHUP. It's important that the pollRead returns true so the socket 
adaptor can attempt a read and throw the exception. If POLLHUP is 
ignored then this will spin.

I know you aren't suggesting it returning false but it's important to 
understand that before coming to the Thread.interrupt case (which is 
what I think you are really asking about). If the thread is interrupted 
when blocked in poll then the begin/end around the blocking call will 
ensure that the channel is closed. This will cause the poll to wakeup. 
It doesn't matter if pollXXX throws AsynchronousCloseException or not as 
the socket adaptor will follow it with a read or finishConnect and that 
will cause the IOException to be thrown. In other words, the value 
passed to end doesn't really matter. It did matter in the 
endFinishConnect case because that caused the channel state to change 
and we don't want that.

As I said in the other mail, it might be better if we add 
beginPoll/endPoll methods that the pollXXX methods could use instead of 
the beginRead/beginFinishConnect etc. That would make it a bit easier to 
understand.

-Alan





More information about the nio-dev mailing list