Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

io.netty.channel.socket.nio.AbstractNioChannel doRegister() ?? #1836

Closed
boboyada opened this issue Sep 13, 2013 · 8 comments
Closed

io.netty.channel.socket.nio.AbstractNioChannel doRegister() ?? #1836

boboyada opened this issue Sep 13, 2013 · 8 comments
Milestone

Comments

@boboyada
Copy link

@OverRide
protected void doRegister() throws Exception {.............
selectionKey = javaChannel().register(eventLoop().selector, 0, this);
what does the "opt==0" means ?
1=OP_READ
2=OP_WRITE
8=OP_CONNECT
16=OP_ACCEPT
0=??

but ,I found that:
NioEventLoop.has method :
private static void processSelectedKey(SelectionKey k, AbstractNioChannel ch) {
............
....................
try {
int readyOps = k.readyOps();
if ((readyOps & (SelectionKey.OP_READ | SelectionKey.OP_ACCEPT)) != 0 || readyOps == 0) {
unsafe.read();
if (!ch.isOpen()) {
// Connection already closed - no need to handle write.
return;
}
}
........
"readyOps==0" ,why?

thanks you!

@normanmaurer
Copy link
Member

@boboyada I think this is a left over and we could remove it.

@trustin agree ?

@trustin
Copy link
Member

trustin commented Sep 15, 2013

It's an intentional stuff to deal with a potential JDK bug where it returns a selection key with readyOps set to 0 for no good reason, leading to a spin loop. So, I'd leave it as it is.

@normanmaurer
Copy link
Member

@trustin maybe we could just have a comment here to know later again why we
have it there ?

2013/9/15 Trustin Lee notifications@github.com

It's an intentional stuff to deal with a potential JDK bug where it
returns a selection key with readyOps set to 0 for no good reason, leading
to a spin loop. So, I'd leave it as it is.


Reply to this email directly or view it on GitHubhttps://github.com//issues/1836#issuecomment-24477435
.

@normanmaurer
Copy link
Member

Added a comment to clearify.

@yingchaozyc
Copy link

for (;;) {
try {
// 在JDK的channel上注册事件 这块没有理解清楚 TODO 注册的数字值是0 是什么意思?岂不是没有事件接受
selectionKey = javaChannel().register(eventLoop().selector, 0, this);
return;
} catch (CancelledKeyException e) {
if (!selected) {
// Force the Selector to select now as the "canceled" SelectionKey may still be
// cached and not removed because no Select.select(..) operation was called yet.
eventLoop().selectNow();
selected = true;
} else {
// We forced a select operation on the selector before but the SelectionKey is still cached
// for whatever reason. JDK bug ?
throw e;
}
}
}

why set 0 in register method? avoid jdk bug here? version4.0.17.final
I can't understand , it's not a questions with blow code:

if ((readyOps & (SelectionKey.OP_READ | SelectionKey.OP_ACCEPT)) != 0 || readyOps == 0) {

@boboyada
Copy link
Author

你好,我很久没有看这个项目了,当时也没有看透。
今天抽空再看了一下。也无法准确回答。这个0注册肯定是不会引起实质性的任何“读”操作的。这种注册只是想判断JDK的selector有没有立刻返回或报错。所以才会在eventloop中有if ((readyOps & (SelectionKey.OP_READ | SelectionKey.OP_ACCEPT)) != 0 || readyOps == 0) {这一判断。
认为注册与绑定,连接是不同的意图。所以在clientboot.connect方法链中,有如下一句
AbstractNioChannel.java
private void fulfillConnectPromise(ChannelPromise promise, boolean wasActive) {
if (!wasActive && isActive()) {
pipeline().fireChannelActive();----》这个方法的实现中,才会出现真正的SelectionKey.OP_READ的注册动作。
}
}

------------------ 原始邮件 ------------------
发件人: "yingchaozyc";notifications@github.com;
发送时间: 2014年5月12日(星期一) 晚上11:49
收件人: "netty/netty"netty@noreply.github.com;
抄送: "ant"287602273@qq.com;
主题: Re: [netty] io.netty.channel.socket.nio.AbstractNioChannel doRegister() ?? (#1836)

for (;;) {
try {
// 在JDK的channel上注册事件 这块没有理解清楚 TODO 注册的数字值是0 是什么意思?岂不是没有事件接受
selectionKey = javaChannel().register(eventLoop().selector, 0, this);
return;
} catch (CancelledKeyException e) {
if (!selected) {
// Force the Selector to select now as the "canceled" SelectionKey may still be
// cached and not removed because no Select.select(..) operation was called yet.
eventLoop().selectNow();
selected = true;
} else {
// We forced a select operation on the selector before but the SelectionKey is still cached
// for whatever reason. JDK bug ?
throw e;
}
}
}

why set 0 in register method? avoid jdk bug here? version4.0.17.final
I can't understand , it's not a questions with blow code:

if ((readyOps & (SelectionKey.OP_READ | SelectionKey.OP_ACCEPT)) != 0 || readyOps == 0) {


Reply to this email directly or view it on GitHub.

@dengyuankai272
Copy link

There are two way to register interested events:

  1. Channel.register()
  2. SelectionKey.interestOps(int)

netty use 2.

After binding channel to selector with interestOps 0, netty will invoke fireChannelActive()
->fire a read event
->HeadContext.unsafe.doBeginRead()
->SelectionKey.interestOps(int)
to set interestOps.

protected void doBeginRead() throws Exception {  
    if (inputShutdown) {  
        return;  
    }  

    final SelectionKey selectionKey = this.selectionKey;  
    if (!selectionKey.isValid()) {  
        return;  
    }  

    final int interestOps = selectionKey.interestOps();  
    if ((interestOps & readInterestOp) == 0) {  
        selectionKey.interestOps(interestOps | readInterestOp);  
    }  
}

@zuoshoulan
Copy link

It took me a day to find the place to register “SelectionKey.OP_ACCEPT”,finally,I found that,case 1 eq case 2

        selector = Selector.open();
        serverSocket = ServerSocketChannel.open();
        serverSocket.configureBlocking(false);
//        SelectionKey sk = serverSocket.register(selector, SelectionKey.OP_ACCEPT); // case 1
        SelectionKey sk = serverSocket.register(selector, 0); //case 2
        serverSocket.socket().bind(new InetSocketAddress(port));
        sk.attach(new Acceptor());

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants