diff --git a/src/main/java/org/jboss/netty/channel/local/DefaultLocalChannel.java b/src/main/java/org/jboss/netty/channel/local/DefaultLocalChannel.java index 14a6da954c..94414d517d 100644 --- a/src/main/java/org/jboss/netty/channel/local/DefaultLocalChannel.java +++ b/src/main/java/org/jboss/netty/channel/local/DefaultLocalChannel.java @@ -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); } diff --git a/src/main/java/org/jboss/netty/channel/socket/nio/NioSocketChannel.java b/src/main/java/org/jboss/netty/channel/socket/nio/NioSocketChannel.java index d449f79fab..c0e22238c1 100644 --- a/src/main/java/org/jboss/netty/channel/socket/nio/NioSocketChannel.java +++ b/src/main/java/org/jboss/netty/channel/socket/nio/NioSocketChannel.java @@ -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() { diff --git a/src/main/java/org/jboss/netty/channel/socket/oio/OioSocketChannel.java b/src/main/java/org/jboss/netty/channel/socket/oio/OioSocketChannel.java index 1a08191645..c8ca59a0a3 100644 --- a/src/main/java/org/jboss/netty/channel/socket/oio/OioSocketChannel.java +++ b/src/main/java/org/jboss/netty/channel/socket/oio/OioSocketChannel.java @@ -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() { diff --git a/src/main/java/org/jboss/netty/channel/xnio/BaseXnioChannel.java b/src/main/java/org/jboss/netty/channel/xnio/BaseXnioChannel.java index 2736ce6e9c..59011d3461 100644 --- a/src/main/java/org/jboss/netty/channel/xnio/BaseXnioChannel.java +++ b/src/main/java/org/jboss/netty/channel/xnio/BaseXnioChannel.java @@ -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 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() {