简体   繁体   中英

Can SelectionKey.isWritable be true without OP_WRITE in interestOps()?

Given a SelectableChannel c and its SelectionKey k, k.isWritable() returns, whether the channel is ready to accept calls to write().

However, can k.isWritable() return true if the channel accepts writes, but OP_WRITE isn't set in interestOps?

No, ready ops is subset of interest ops. if key isn't interested in write, selector will not set its write ready op (which does not mean it cannot accept write. you can call write() anytime. with write-ready, write() is very likely to succeed, but there's not guarantee there either)

There is a catch, which costs me several hours to figure out. Consider the following code:

SocketChannel socket = SocketChannel.open(new InetSocketAddress("127.0.0.1", 22));
socket.configureBlocking(false);
Selector selector = Selector.open();
SelectionKey selkey = socket.register(selector, 0);
....
selkey.interestOps(SelectionKey.OP_READ);
selector.select(1000);
System.out.println("Selecting r, return " +
  (selector.selectedKeys().contains(selkey) && selkey.isReadable() ? "r" : "") +
  (selector.selectedKeys().contains(selkey) && selkey.isWritable() ? "w" : ""));

It prints "Selecting r, return w". So it is possible for isWritable() to be true while only OP_READ is interested. This happens if OP_WRITE is included in a previous select() call and the current select() returns 0, which means selkey is not updated.

The complete proof code is here: https://gist.github.com/wuyongzheng/43cc9dc07e13124663d1 . To run, you need a SSH server at port 22.

Actually it can: if you OP_WRITE is set first,then key.interestOps(0); key.isWritable() will return true.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM