4

When i have a selector.select() registered to a SocketChannel, and i close the SocketChannel's peer in a separate thread, selector.select() returns, and that channel's READ operation is set. If i have a ServerSocketChannel registered to the selector, and i close the ServerSocketChannel, selector.select() does not return. Is there anyway i can detect that the ServerSocketChannel was closed while being blocked in selector.select()?

I tried using selector.wakeup(), and going through the set of keys (not selected keys), and seeing if there are any unopened channels in the set, but as soon as the close is done on the ServerSocketChannel, it is deregistered from selector, so it is not in the select.keys() set.

user9058115
  • 161
  • 5
  • Why? It's closed. There's nothing fiurther you need to do it it. There is nothing further you *can* do with it. Anything you need to do to your own data structures can be done at the point where you close it. – user207421 Feb 20 '19 at 22:10
  • @user207421, when all the channels are closed, i want the the thread to exit. if the only channel left open is the ServerSocketChannel, and it get's closed, i was hoping there was a way select() would exit, i would see there was no channels left registered to the selector, and the thread would exit. – user9058115 Feb 20 '19 at 23:16
  • So exit when the number of registered channels falls to zero. – user207421 Feb 20 '19 at 23:18
  • NB Your claim about what happens if you close a registered `SocketChannel` is not correct. What actually happens is that the key is cancelled, just as for the `ServerSocketChannel`, and it is therefore *excluded* from the selected-key set, and indeed it has been removed from the registered key set. It is therefore not possible for its `SelectionKey` to be readable. Even if you saved it separately it throws `CancelledKeyException` why you try to use it. What you describe occurs when the *peer* closes the connection. – user207421 Feb 21 '19 at 03:17
  • @user207421, you are correct. i meant when the peer is closed, not the SocketChannel is closed. Which makes it more clear why when i close the ServerSocketChannel, select does not return. I will edit my question to make it clear. – user9058115 Feb 21 '19 at 19:42

1 Answers1

1

Is there anyway i can detect that the ServerSocketChannel was closed while being blocked in selector.select()?

If you want selector.select() returns so you can extract the closed channel in selected keys then no. As docs says

It returns only after at least one channel is selected, this selector's wakeup method is invoked, or the current thread is interrupted, whichever comes first.

Since there is no such interest op like OP_CLOSE the only way to make select method return on channel close is to wakeup explicitly. But the key is implicitly cancelled.

Anyway, it not that much you can do with a closed channel.

Also EPollSelectorProvider is proxying calls to the underlying epoll and it does not have an event like you want either. http://man7.org/linux/man-pages/man2/epoll_ctl.2.html

Some Name
  • 8,555
  • 5
  • 27
  • 77
  • You have to wakeup the `Selector` after you close the `ServerSocketChannel` otherwise the registration and object pointers will remain and cannot be garbage-collected. It will automatically remove from the `Selector` after waking because the `SelectionKey` is cancelled when you manually close the `ServerSocketChannel`. – Johnny V Feb 26 '19 at 18:49