Fix infinity loop and timing issues

- Made sure unnecessary interestOps are not OR'd
- Fixed a bug where DefaultChannelFuture.rethrowIfFailed() returns
  silently if the future is not done yet - there's no ways to tell
  the differences between failure and incompleteness.
This commit is contained in:
Trustin Lee 2012-05-09 23:42:01 +09:00
parent 129a2af86a
commit b4764f6164
8 changed files with 26 additions and 19 deletions

View File

@ -88,7 +88,7 @@ public class EchoServer {
});
loop.register(ssc).awaitUninterruptibly().rethrowIfFailed();
ssc.bind(new InetSocketAddress(port), ssc.newFuture());
ssc.bind(new InetSocketAddress(port), ssc.newFuture()).awaitUninterruptibly().rethrowIfFailed();
}
public static void main(String[] args) throws Exception {

View File

@ -20,6 +20,7 @@ import io.netty.logging.InternalLoggerFactory;
import io.netty.util.DefaultAttributeMap;
import io.netty.util.internal.ConcurrentHashMap;
import java.io.IOException;
import java.net.SocketAddress;
import java.nio.channels.ClosedChannelException;
import java.util.ArrayList;
@ -658,7 +659,7 @@ public abstract class AbstractChannel extends DefaultAttributeMap implements Cha
// FIXME: Wrap with a loop
long readAmount = 0;
try {
boolean closeIfClosed = false;
boolean closed = false;
for (;;) {
int localReadAmount = doRead();
if (localReadAmount > 0) {
@ -669,7 +670,7 @@ public abstract class AbstractChannel extends DefaultAttributeMap implements Cha
break;
}
if (localReadAmount < 0) {
closeIfClosed = true;
closed = true;
break;
}
}
@ -678,12 +679,14 @@ public abstract class AbstractChannel extends DefaultAttributeMap implements Cha
pipeline.fireInboundBufferUpdated();
}
if (closeIfClosed) {
closeIfClosed();
if (closed) {
close(newFuture());
}
} catch (Throwable t) {
pipeline().fireExceptionCaught(t);
closeIfClosed();
if (t instanceof IOException) {
close(newFuture());
}
}
}
@ -725,7 +728,7 @@ public abstract class AbstractChannel extends DefaultAttributeMap implements Cha
if (isOpen()) {
return;
}
close(newFuture());
close(newVoidFuture());
}
}

View File

@ -190,7 +190,7 @@ public class DefaultChannelFuture implements ChannelFuture {
@Override
public ChannelFuture rethrowIfFailed() throws Exception {
if (!isDone()) {
return this;
throw new IllegalStateException("not done yet");
}
Throwable cause = cause();

View File

@ -87,6 +87,6 @@ public abstract class AbstractNioChannel extends AbstractChannel {
}
SelectorEventLoop loop = (SelectorEventLoop) eventLoop();
selectionKey = javaChannel().register(loop.selector, javaChannel().validOps() & ~SelectionKey.OP_WRITE, this);
selectionKey = javaChannel().register(loop.selector, SelectionKey.OP_READ, this);
}
}

View File

@ -75,8 +75,7 @@ public class NioServerSocketChannel extends AbstractServerChannel
@Override
public boolean isActive() {
// TODO Auto-generated method stub
return false;
return javaChannel().socket().isBound();
}
@Override
@ -116,12 +115,14 @@ public class NioServerSocketChannel extends AbstractServerChannel
}
SelectorEventLoop loop = (SelectorEventLoop) eventLoop();
selectionKey = javaChannel().register(loop.selector, javaChannel().validOps(), this);
selectionKey = javaChannel().register(
loop.selector, isActive()? SelectionKey.OP_ACCEPT : 0, this);
}
@Override
protected void doBind(SocketAddress localAddress) throws Exception {
javaChannel().socket().bind(localAddress);
selectionKey.interestOps(selectionKey.interestOps() | SelectionKey.OP_ACCEPT);
}
@Override

View File

@ -116,6 +116,9 @@ public class NioSocketChannel extends AbstractNioChannel implements io.netty.cha
boolean success = false;
try {
boolean connected = javaChannel().connect(remoteAddress);
if (!connected) {
selectionKey().interestOps(selectionKey().interestOps() | SelectionKey.OP_CONNECT);
}
success = true;
return connected;
} finally {

View File

@ -55,6 +55,7 @@ public class SelectorEventLoop extends SingleThreadEventLoop {
*/
protected final AtomicBoolean wakenUp = new AtomicBoolean();
// FIXME: It's not being increased by any channel implementations but we have to.
private volatile int cancelledKeys; // should use AtomicInteger but we just need approximation
public SelectorEventLoop() {
@ -199,7 +200,6 @@ public class SelectorEventLoop extends SingleThreadEventLoop {
if ((readyOps & SelectionKey.OP_WRITE) != 0) {
ch.unsafe().flush(null);
}
if ((readyOps & SelectionKey.OP_ACCEPT) != 0) {
ch.unsafe().read();
}

View File

@ -15,13 +15,13 @@
*/
package io.netty.channel.socket.nio;
import io.netty.logging.InternalLogger;
import io.netty.logging.InternalLoggerFactory;
import java.io.IOException;
import java.nio.channels.CancelledKeyException;
import java.nio.channels.Selector;
import io.netty.logging.InternalLogger;
import io.netty.logging.InternalLoggerFactory;
public final class SelectorUtil {
private static final InternalLogger logger =
InternalLoggerFactory.getInstance(SelectorUtil.class);
@ -30,10 +30,10 @@ public final class SelectorUtil {
public static final int DEFAULT_IO_ACCEPTING_THREADS = 1;
// Workaround for JDK NIO bug.
//
// See:
// See:
// - http://bugs.sun.com/view_bug.do?bug_id=6427854
// - https://github.com/netty/netty/issues/203
static {
@ -49,7 +49,7 @@ public final class SelectorUtil {
}
}
}
static void select(Selector selector) throws IOException {
try {
selector.select(10);