Store datagram channel's remoteAddress as much as possible within the extent that does not cause a race condition

This commit is contained in:
Trustin Lee 2009-06-30 09:17:50 +00:00
parent 959e72a6b0
commit c0267a9e4f
4 changed files with 41 additions and 14 deletions

View File

@ -22,7 +22,8 @@
*/
package org.jboss.netty.channel.socket.nio;
import static org.jboss.netty.channel.Channels.*;
import static org.jboss.netty.channel.Channels.fireChannelInterestChanged;
import static org.jboss.netty.channel.Channels.fireChannelOpen;
import java.io.IOException;
import java.net.InetAddress;
@ -121,6 +122,7 @@ class NioDatagramChannel extends AbstractChannel
volatile boolean inWriteNowLoop;
private volatile InetSocketAddress localAddress;
volatile InetSocketAddress remoteAddress;
NioDatagramChannel(final ChannelFactory factory,
final ChannelPipeline pipeline, final ChannelSink sink,
@ -158,12 +160,17 @@ class NioDatagramChannel extends AbstractChannel
}
public InetSocketAddress getRemoteAddress() {
try {
return (InetSocketAddress) datagramChannel.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) datagramChannel.socket().getRemoteSocketAddress();
} catch (Throwable t) {
// Sometimes fails on a closed socket in Windows.
return null;
}
}
return remoteAddress;
}
public boolean isBound() {

View File

@ -22,7 +22,11 @@
*/
package org.jboss.netty.channel.socket.nio;
import static org.jboss.netty.channel.Channels.*;
import static org.jboss.netty.channel.Channels.fireChannelBound;
import static org.jboss.netty.channel.Channels.fireChannelClosed;
import static org.jboss.netty.channel.Channels.fireChannelConnected;
import static org.jboss.netty.channel.Channels.fireChannelUnbound;
import static org.jboss.netty.channel.Channels.fireExceptionCaught;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
@ -174,6 +178,10 @@ class NioDatagramPipelineSink extends AbstractChannelSink {
future.addListener(ChannelFutureListener.CLOSE_ON_FAILURE);
// Clear the cached address so that the next getRemoteAddress() call
// updates the cache.
channel.remoteAddress = null;
try {
channel.getDatagramChannel().connect(remoteAddress);
connected = true;

View File

@ -22,7 +22,7 @@
*/
package org.jboss.netty.channel.socket.oio;
import static org.jboss.netty.channel.Channels.*;
import static org.jboss.netty.channel.Channels.fireChannelOpen;
import java.io.IOException;
import java.net.InetAddress;
@ -58,6 +58,7 @@ final class OioDatagramChannel extends AbstractChannel
private final DatagramChannelConfig config;
volatile Thread workerThread;
private volatile InetSocketAddress localAddress;
volatile InetSocketAddress remoteAddress;
OioDatagramChannel(
ChannelFactory factory,
@ -102,12 +103,17 @@ final class OioDatagramChannel extends AbstractChannel
}
public InetSocketAddress getRemoteAddress() {
try {
return (InetSocketAddress) 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.getRemoteSocketAddress();
} catch (Throwable t) {
// Sometimes fails on a closed socket in Windows.
return null;
}
}
return remoteAddress;
}
public boolean isBound() {

View File

@ -22,7 +22,9 @@
*/
package org.jboss.netty.channel.socket.oio;
import static org.jboss.netty.channel.Channels.*;
import static org.jboss.netty.channel.Channels.fireChannelBound;
import static org.jboss.netty.channel.Channels.fireChannelConnected;
import static org.jboss.netty.channel.Channels.fireExceptionCaught;
import java.net.SocketAddress;
import java.util.concurrent.Executor;
@ -135,6 +137,10 @@ class OioDatagramPipelineSink extends AbstractChannelSink {
future.addListener(ChannelFutureListener.CLOSE_ON_FAILURE);
// Clear the cached address so that the next getRemoteAddress() call
// updates the cache.
channel.remoteAddress = null;
try {
channel.socket.connect(remoteAddress);
connected = true;