Add ChannelFutureFactory & removeClosureListener()

- Channel and ChannelHandlerContext extends ChannelFutureFactory.
- Added Channel.removeClosureListener()
This commit is contained in:
Trustin Lee 2012-05-01 17:48:06 +09:00
parent 368156f5d0
commit 825d7964c9
5 changed files with 48 additions and 17 deletions

View File

@ -53,8 +53,9 @@ public abstract class AbstractChannel extends DefaultAttributeMap implements Cha
private final Integer id;
private final Channel parent;
private final Unsafe unsafe;
private final DefaultChannelPipeline pipeline = new DefaultChannelPipeline(this);
private final ChannelPipeline pipeline = new DefaultChannelPipeline(this);
private final List<ChannelFutureListener> closureListeners = new ArrayList<ChannelFutureListener>(4);
private final ChannelFuture succeededFuture = new SucceededChannelFuture(this);
private volatile EventLoop eventLoop;
private volatile boolean notifiedClosureListeners;
@ -160,6 +161,24 @@ public abstract class AbstractChannel extends DefaultAttributeMap implements Cha
pipeline.write(message, future);
}
@Override
public ChannelFuture newFuture() {
return new DefaultChannelFuture(this, false);
}
@Override
public ChannelFuture newSucceededFuture() {
return succeededFuture;
}
@Override
public ChannelFuture newFailedFuture(Throwable cause) {
return new FailedChannelFuture(this, cause);
}
@Override
public void addClosureListener(final ChannelFutureListener listener) {
if (listener == null) {
@ -179,6 +198,18 @@ public abstract class AbstractChannel extends DefaultAttributeMap implements Cha
}
}
@Override
public void removeClosureListener(ChannelFutureListener listener) {
if (listener == null) {
throw new NullPointerException("listener");
}
synchronized (closureListeners) {
if (!notifiedClosureListeners) {
closureListeners.remove(listener);
}
}
}
/**
* A {@link Channel} implementation must call this method when it is closed.
*/
@ -205,7 +236,7 @@ public abstract class AbstractChannel extends DefaultAttributeMap implements Cha
private void notifyClosureListener(final ChannelFutureListener listener) {
try {
listener.operationComplete(pipeline.succeededFuture());
listener.operationComplete(newSucceededFuture());
} catch (Exception e) {
logger.warn("Failed to notify a closure listener.", e);
}

View File

@ -106,7 +106,7 @@ import java.nio.channels.SelectionKey;
*
* @apiviz.exclude ^io\.netty\.channel\.([a-z]+\.)+[^\.]+Channel$
*/
public interface Channel extends AttributeMap, Comparable<Channel> {
public interface Channel extends AttributeMap, ChannelFutureFactory, Comparable<Channel> {
/**
* Returns the unique integer ID of this channel.
@ -176,6 +176,7 @@ public interface Channel extends AttributeMap, Comparable<Channel> {
void write(Object message, ChannelFuture future);
void addClosureListener(ChannelFutureListener listener);
void removeClosureListener(ChannelFutureListener remover);
Unsafe unsafe();

View File

@ -0,0 +1,7 @@
package io.netty.channel;
public interface ChannelFutureFactory {
ChannelFuture newFuture();
ChannelFuture newSucceededFuture();
ChannelFuture newFailedFuture(Throwable cause);
}

View File

@ -18,6 +18,8 @@ package io.netty.channel;
import io.netty.util.AttributeMap;
import java.nio.channels.Channels;
/**
* Enables a {@link ChannelHandler} to interact with its {@link ChannelPipeline}
* and other handlers. A handler can send a {@link ChannelEvent} upstream or
@ -120,7 +122,7 @@ import io.netty.util.AttributeMap;
* pipeline, and how to handle the event in your application.
* @apiviz.owns io.netty.channel.ChannelHandler
*/
public interface ChannelHandlerContext extends AttributeMap, ChannelHandlerInvoker {
public interface ChannelHandlerContext extends AttributeMap, ChannelHandlerInvoker, ChannelFutureFactory {
Channel channel();
ChannelPipeline pipeline();
@ -129,8 +131,4 @@ public interface ChannelHandlerContext extends AttributeMap, ChannelHandlerInvok
boolean canHandleInbound();
boolean canHandleOutbound();
ChannelFuture newFuture();
ChannelFuture newSucceededFuture();
ChannelFuture newFailedFuture(Throwable cause);
}

View File

@ -37,7 +37,6 @@ public class DefaultChannelPipeline implements ChannelPipeline {
static final InternalLogger logger = InternalLoggerFactory.getInstance(DefaultChannelPipeline.class);
private final Channel channel;
private final ChannelFuture succeededFuture;
private volatile DefaultChannelHandlerContext head;
private volatile DefaultChannelHandlerContext tail;
private final Map<String, DefaultChannelHandlerContext> name2ctx =
@ -48,7 +47,6 @@ public class DefaultChannelPipeline implements ChannelPipeline {
throw new NullPointerException("channel");
}
this.channel = channel;
succeededFuture = new SucceededChannelFuture(channel);
}
@Override
@ -56,10 +54,6 @@ public class DefaultChannelPipeline implements ChannelPipeline {
return channel;
}
ChannelFuture succeededFuture() {
return succeededFuture;
}
@Override
public synchronized void addFirst(String name, ChannelHandler handler) {
if (name2ctx.isEmpty()) {
@ -1138,17 +1132,17 @@ public class DefaultChannelPipeline implements ChannelPipeline {
@Override
public ChannelFuture newFuture() {
return new DefaultChannelFuture(channel(), false);
return channel().newFuture();
}
@Override
public ChannelFuture newSucceededFuture() {
return succeededFuture();
return channel().newSucceededFuture();
}
@Override
public ChannelFuture newFailedFuture(Throwable cause) {
return new FailedChannelFuture(channel(), cause);
return channel().newFailedFuture(cause);
}
}
}