Fixed issue: NETTY-180 Channel.getRemoteAddress() can return null for a received MessageEvent when ExecutionHandler is in the pipeline.

* All Channel implementations but DatagramChannel now cache localAddress and remoteAddress so that they do not return null even after the connection has been closed.
This commit is contained in:
Trustin Lee 2009-06-23 07:46:59 +00:00
parent 8448188706
commit 5698904374
4 changed files with 71 additions and 27 deletions

View File

@ -69,15 +69,15 @@ final class DefaultLocalChannel extends AbstractChannel implements LocalChannel
}
public boolean isBound() {
return isOpen() && bound.get();
return bound.get() && isOpen();
}
public boolean isConnected() {
return localAddress != null && remoteAddress != null;
return pairedChannel != null && isOpen();
}
public LocalAddress getLocalAddress() {
return isBound()? localAddress : null;
return localAddress;
}
public LocalAddress getRemoteAddress() {
@ -95,7 +95,6 @@ final class DefaultLocalChannel extends AbstractChannel implements LocalChannel
DefaultLocalChannel pairedChannel = this.pairedChannel;
if (pairedChannel != null) {
this.pairedChannel = null;
this.localAddress = null;
fireChannelDisconnected(this);
fireChannelUnbound(this);
}
@ -109,7 +108,6 @@ final class DefaultLocalChannel extends AbstractChannel implements LocalChannel
DefaultLocalChannel me = pairedChannel.pairedChannel;
if (me != null) {
pairedChannel.pairedChannel = null;
pairedChannel.localAddress = null;
fireChannelDisconnected(pairedChannel);
fireChannelUnbound(pairedChannel);
}

View File

@ -55,6 +55,8 @@ class NioSocketChannel extends AbstractChannel
final SocketChannel socket;
final NioWorker worker;
private final NioSocketChannelConfig config;
private volatile InetSocketAddress localAddress;
private volatile InetSocketAddress remoteAddress;
final Object interestOpsLock = new Object();
final Object writeLock = new Object();
@ -86,21 +88,31 @@ class NioSocketChannel extends AbstractChannel
}
public InetSocketAddress getLocalAddress() {
try {
return (InetSocketAddress) socket.socket().getLocalSocketAddress();
} catch (Throwable t) {
// Sometimes fails on a closed socket in Windows.
return null;
InetSocketAddress localAddress = this.localAddress;
if (localAddress == null) {
try {
this.localAddress = localAddress =
(InetSocketAddress) socket.socket().getLocalSocketAddress();
} catch (Throwable t) {
// Sometimes fails on a closed socket in Windows.
return null;
}
}
return localAddress;
}
public InetSocketAddress getRemoteAddress() {
try {
return (InetSocketAddress) socket.socket().getRemoteSocketAddress();
} catch (Throwable t) {
// Sometimes fails on a closed socket in Windows.
return null;
InetSocketAddress remoteAddress = this.remoteAddress;
if (remoteAddress == null) {
try {
this.remoteAddress = remoteAddress =
(InetSocketAddress) socket.socket().getRemoteSocketAddress();
} catch (Throwable t) {
// Sometimes fails on a closed socket in Windows.
return null;
}
}
return remoteAddress;
}
public boolean isBound() {

View File

@ -53,6 +53,8 @@ abstract class OioSocketChannel extends AbstractChannel
final Object interestOpsLock = new Object();
private final SocketChannelConfig config;
volatile Thread workerThread;
private volatile InetSocketAddress localAddress;
private volatile InetSocketAddress remoteAddress;
OioSocketChannel(
Channel parent,
@ -72,11 +74,31 @@ abstract class OioSocketChannel extends AbstractChannel
}
public InetSocketAddress getLocalAddress() {
return (InetSocketAddress) socket.getLocalSocketAddress();
InetSocketAddress localAddress = this.localAddress;
if (localAddress == null) {
try {
this.localAddress = localAddress =
(InetSocketAddress) socket.getLocalSocketAddress();
} catch (Throwable t) {
// Sometimes fails on a closed socket in Windows.
return null;
}
}
return localAddress;
}
public InetSocketAddress getRemoteAddress() {
return (InetSocketAddress) socket.getRemoteSocketAddress();
InetSocketAddress remoteAddress = this.remoteAddress;
if (remoteAddress == null) {
try {
this.remoteAddress = remoteAddress =
(InetSocketAddress) socket.getRemoteSocketAddress();
} catch (Throwable t) {
// Sometimes fails on a closed socket in Windows.
return null;
}
}
return remoteAddress;
}
public boolean isBound() {

View File

@ -55,6 +55,8 @@ class BaseXnioChannel extends AbstractChannel implements XnioChannel {
private final XnioChannelConfig config;
volatile java.nio.channels.Channel xnioChannel;
private volatile SocketAddress localAddress;
private volatile SocketAddress remoteAddress;
final Object writeLock = new Object();
final Queue<MessageEvent> writeBuffer = new WriteBuffer();
@ -76,21 +78,31 @@ class BaseXnioChannel extends AbstractChannel implements XnioChannel {
}
public SocketAddress getLocalAddress() {
java.nio.channels.Channel xnioChannel = this.xnioChannel;
if (!isOpen() || !(xnioChannel instanceof BoundChannel)) {
return null;
}
SocketAddress localAddress = this.localAddress;
if (localAddress == null) {
java.nio.channels.Channel xnioChannel = this.xnioChannel;
if (!isOpen() || !(xnioChannel instanceof BoundChannel)) {
return null;
}
return (SocketAddress) ((BoundChannel) xnioChannel).getLocalAddress();
this.localAddress = localAddress =
(SocketAddress) ((BoundChannel) xnioChannel).getLocalAddress();
}
return localAddress;
}
public SocketAddress getRemoteAddress() {
java.nio.channels.Channel xnioChannel = this.xnioChannel;
if (!isOpen() || !(xnioChannel instanceof ConnectedChannel)) {
return null;
}
SocketAddress remoteAddress = this.remoteAddress;
if (remoteAddress == null) {
java.nio.channels.Channel xnioChannel = this.xnioChannel;
if (!isOpen() || !(xnioChannel instanceof ConnectedChannel)) {
return null;
}
return (SocketAddress) ((ConnectedChannel) xnioChannel).getPeerAddress();
this.remoteAddress = remoteAddress =
(SocketAddress) ((ConnectedChannel) xnioChannel).getPeerAddress();
}
return remoteAddress;
}
public boolean isBound() {