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:
parent
129a2af86a
commit
b4764f6164
@ -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 {
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user