[#965] Allow to adjust the SO_TIMEOUT on the fly
This commit is contained in:
parent
29bed32a89
commit
7316a3c65c
@ -59,6 +59,8 @@ public class ChannelOption<T> extends UniqueName {
|
||||
new ChannelOption<Integer>("SO_LINGER");
|
||||
public static final ChannelOption<Integer> SO_BACKLOG =
|
||||
new ChannelOption<Integer>("SO_BACKLOG");
|
||||
public static final ChannelOption<Integer> SO_TIMEOUT =
|
||||
new ChannelOption<Integer>("SO_TIMEOUT");
|
||||
|
||||
public static final ChannelOption<Integer> IP_TOS =
|
||||
new ChannelOption<Integer>("IP_TOS");
|
||||
|
@ -33,7 +33,7 @@ import static io.netty.channel.ChannelOption.*;
|
||||
public class DefaultServerSocketChannelConfig extends DefaultChannelConfig
|
||||
implements ServerSocketChannelConfig {
|
||||
|
||||
private final ServerSocket javaSocket;
|
||||
protected final ServerSocket javaSocket;
|
||||
private volatile int backlog = NetUtil.SOMAXCONN;
|
||||
|
||||
/**
|
||||
|
@ -32,7 +32,7 @@ import static io.netty.channel.ChannelOption.*;
|
||||
public class DefaultSocketChannelConfig extends DefaultChannelConfig
|
||||
implements SocketChannelConfig {
|
||||
|
||||
private final Socket javaSocket;
|
||||
protected final Socket javaSocket;
|
||||
private volatile boolean allowHalfClosure;
|
||||
|
||||
/**
|
||||
|
@ -49,14 +49,25 @@ public abstract class AbstractOioByteChannel extends AbstractOioChannel {
|
||||
return METADATA;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doRead() {
|
||||
/**
|
||||
* Check if the input was shutdown and if so return {@code true}. The default implementation sleeps also for
|
||||
* {@link #SO_TIMEOUT} milliseconds to simulate some blocking.
|
||||
*/
|
||||
protected boolean checkInputShutdown() {
|
||||
if (inputShutdown) {
|
||||
try {
|
||||
Thread.sleep(SO_TIMEOUT);
|
||||
} catch (InterruptedException e) {
|
||||
// ignore
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doRead() {
|
||||
if (checkInputShutdown()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright 2013 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you under the Apache License,
|
||||
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package io.netty.channel.socket.oio;
|
||||
|
||||
import io.netty.channel.ChannelException;
|
||||
import io.netty.channel.ChannelOption;
|
||||
import io.netty.channel.socket.DefaultServerSocketChannelConfig;
|
||||
import io.netty.channel.socket.ServerSocketChannel;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.ServerSocket;
|
||||
import java.util.Map;
|
||||
|
||||
import static io.netty.channel.ChannelOption.SO_TIMEOUT;
|
||||
|
||||
/**
|
||||
* Default {@link OioServerSocketChannelConfig} implementation
|
||||
*/
|
||||
public class DefaultOioServerSocketChannelConfig extends DefaultServerSocketChannelConfig implements
|
||||
OioServerSocketChannelConfig {
|
||||
|
||||
public DefaultOioServerSocketChannelConfig(ServerSocketChannel channel, ServerSocket javaSocket) {
|
||||
super(channel, javaSocket);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ChannelOption<?>, Object> getOptions() {
|
||||
return getOptions(
|
||||
super.getOptions(), SO_TIMEOUT);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T> T getOption(ChannelOption<T> option) {
|
||||
if (option == SO_TIMEOUT) {
|
||||
return (T) Integer.valueOf(getSoTimeout());
|
||||
}
|
||||
return super.getOption(option);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> boolean setOption(ChannelOption<T> option, T value) {
|
||||
validate(option, value);
|
||||
|
||||
if (option == SO_TIMEOUT) {
|
||||
setSoTimeout((Integer) value);
|
||||
} else {
|
||||
return super.setOption(option, value);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSoTimeout(int timeout) {
|
||||
try {
|
||||
javaSocket.setSoTimeout(timeout);
|
||||
} catch (IOException e) {
|
||||
throw new ChannelException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSoTimeout() {
|
||||
try {
|
||||
return javaSocket.getSoTimeout();
|
||||
} catch (IOException e) {
|
||||
throw new ChannelException(e);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright 2013 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you under the Apache License,
|
||||
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package io.netty.channel.socket.oio;
|
||||
|
||||
import io.netty.channel.ChannelException;
|
||||
import io.netty.channel.ChannelOption;
|
||||
import io.netty.channel.socket.DefaultSocketChannelConfig;
|
||||
import io.netty.channel.socket.SocketChannel;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.Socket;
|
||||
import java.util.Map;
|
||||
|
||||
import static io.netty.channel.ChannelOption.*;
|
||||
|
||||
/**
|
||||
* Default {@link OioSocketChannelConfig} implementation
|
||||
*/
|
||||
public class DefaultOioSocketChannelConfig extends DefaultSocketChannelConfig implements OioSocketChannelConfig {
|
||||
public DefaultOioSocketChannelConfig(SocketChannel channel, Socket javaSocket) {
|
||||
super(channel, javaSocket);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ChannelOption<?>, Object> getOptions() {
|
||||
return getOptions(
|
||||
super.getOptions(), SO_TIMEOUT);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T> T getOption(ChannelOption<T> option) {
|
||||
if (option == SO_TIMEOUT) {
|
||||
return (T) Integer.valueOf(getSoTimeout());
|
||||
}
|
||||
return super.getOption(option);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> boolean setOption(ChannelOption<T> option, T value) {
|
||||
validate(option, value);
|
||||
|
||||
if (option == SO_TIMEOUT) {
|
||||
setSoTimeout((Integer) value);
|
||||
} else {
|
||||
return super.setOption(option, value);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSoTimeout(int timeout) {
|
||||
try {
|
||||
javaSocket.setSoTimeout(timeout);
|
||||
} catch (IOException e) {
|
||||
throw new ChannelException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSoTimeout() {
|
||||
try {
|
||||
return javaSocket.getSoTimeout();
|
||||
} catch (IOException e) {
|
||||
throw new ChannelException(e);
|
||||
}
|
||||
}
|
||||
}
|
@ -19,9 +19,7 @@ import io.netty.buffer.BufType;
|
||||
import io.netty.buffer.MessageBuf;
|
||||
import io.netty.channel.ChannelException;
|
||||
import io.netty.channel.ChannelMetadata;
|
||||
import io.netty.channel.socket.DefaultServerSocketChannelConfig;
|
||||
import io.netty.channel.socket.ServerSocketChannel;
|
||||
import io.netty.channel.socket.ServerSocketChannelConfig;
|
||||
import io.netty.logging.InternalLogger;
|
||||
import io.netty.logging.InternalLoggerFactory;
|
||||
|
||||
@ -57,7 +55,7 @@ public class OioServerSocketChannel extends AbstractOioMessageChannel
|
||||
|
||||
final ServerSocket socket;
|
||||
final Lock shutdownLock = new ReentrantLock();
|
||||
private final ServerSocketChannelConfig config;
|
||||
private final OioServerSocketChannelConfig config;
|
||||
|
||||
/**
|
||||
* Create a new instance with an new {@link Socket}
|
||||
@ -106,9 +104,8 @@ public class OioServerSocketChannel extends AbstractOioMessageChannel
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.socket = socket;
|
||||
config = new DefaultServerSocketChannelConfig(this, socket);
|
||||
config = new DefaultOioServerSocketChannelConfig(this, socket);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -117,7 +114,7 @@ public class OioServerSocketChannel extends AbstractOioMessageChannel
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServerSocketChannelConfig config() {
|
||||
public OioServerSocketChannelConfig config() {
|
||||
return config;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2013 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you under the Apache License,
|
||||
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package io.netty.channel.socket.oio;
|
||||
|
||||
import io.netty.channel.socket.ServerSocketChannelConfig;
|
||||
|
||||
|
||||
/**
|
||||
* A {@link ServerSocketChannelConfig} for a {@link OioServerSocketChannel}.
|
||||
*
|
||||
* <h3>Available options</h3>
|
||||
*
|
||||
* In addition to the options provided by {@link ServerSocketChannelConfig},
|
||||
* {@link OioServerSocketChannelConfig} allows the following options in the
|
||||
* option map:
|
||||
*
|
||||
* <table border="1" cellspacing="0" cellpadding="6">
|
||||
* <tr>
|
||||
* <th>Name</th><th>Associated setter method</th>
|
||||
* </tr><tr>
|
||||
* <td>{@link io.netty.channel.ChannelOption#SO_TIMEOUT}</td><td>{@link #setSoTimeout(int)}</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*/
|
||||
public interface OioServerSocketChannelConfig extends ServerSocketChannelConfig {
|
||||
|
||||
/**
|
||||
* Sets the maximal time a operation on the underlying socket may block.
|
||||
*/
|
||||
void setSoTimeout(int timeout);
|
||||
|
||||
/**
|
||||
* Returns the maximal time a operation on the underlying socket may block.
|
||||
*/
|
||||
int getSoTimeout();
|
||||
}
|
@ -21,10 +21,8 @@ import io.netty.channel.ChannelException;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelPromise;
|
||||
import io.netty.channel.EventLoop;
|
||||
import io.netty.channel.socket.DefaultSocketChannelConfig;
|
||||
import io.netty.channel.socket.ServerSocketChannel;
|
||||
import io.netty.channel.socket.SocketChannel;
|
||||
import io.netty.channel.socket.SocketChannelConfig;
|
||||
import io.netty.logging.InternalLogger;
|
||||
import io.netty.logging.InternalLoggerFactory;
|
||||
|
||||
@ -44,7 +42,7 @@ public class OioSocketChannel extends StreamOioByteChannel
|
||||
InternalLoggerFactory.getInstance(OioSocketChannel.class);
|
||||
|
||||
private final Socket socket;
|
||||
private final SocketChannelConfig config;
|
||||
private final OioSocketChannelConfig config;
|
||||
|
||||
/**
|
||||
* Create a new instance with an new {@link Socket}
|
||||
@ -73,7 +71,7 @@ public class OioSocketChannel extends StreamOioByteChannel
|
||||
public OioSocketChannel(Channel parent, Integer id, Socket socket) {
|
||||
super(parent, id);
|
||||
this.socket = socket;
|
||||
config = new DefaultSocketChannelConfig(this, socket);
|
||||
config = new DefaultOioSocketChannelConfig(this, socket);
|
||||
|
||||
boolean success = false;
|
||||
try {
|
||||
@ -101,7 +99,7 @@ public class OioSocketChannel extends StreamOioByteChannel
|
||||
}
|
||||
|
||||
@Override
|
||||
public SocketChannelConfig config() {
|
||||
public OioSocketChannelConfig config() {
|
||||
return config;
|
||||
}
|
||||
|
||||
@ -216,4 +214,17 @@ public class OioSocketChannel extends StreamOioByteChannel
|
||||
protected void doClose() throws Exception {
|
||||
socket.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean checkInputShutdown() {
|
||||
if (isInputShutdown()) {
|
||||
try {
|
||||
Thread.sleep(config().getSoTimeout());
|
||||
} catch (Throwable e) {
|
||||
// ignore
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2013 The Netty Project
|
||||
*
|
||||
* The Netty Project licenses this file to you under the Apache License,
|
||||
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package io.netty.channel.socket.oio;
|
||||
|
||||
import io.netty.channel.ChannelConfig;
|
||||
import io.netty.channel.socket.SocketChannelConfig;
|
||||
|
||||
/**
|
||||
* A {@link ChannelConfig} for a {@link OioSocketChannel}.
|
||||
*
|
||||
* <h3>Available options</h3>
|
||||
*
|
||||
* In addition to the options provided by {@link SocketChannelConfig},
|
||||
* {@link OioSocketChannelConfig} allows the following options in the
|
||||
* option map:
|
||||
*
|
||||
* <table border="1" cellspacing="0" cellpadding="6">
|
||||
* <tr>
|
||||
* <th>Name</th><th>Associated setter method</th>
|
||||
* </tr><tr>
|
||||
* <td>{@link io.netty.channel.ChannelOption#SO_TIMEOUT}</td><td>{@link #setSoTimeout(int)}</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*/
|
||||
public interface OioSocketChannelConfig extends SocketChannelConfig {
|
||||
|
||||
/**
|
||||
* Sets the maximal time a operation on the underlying socket may block.
|
||||
*/
|
||||
void setSoTimeout(int timeout);
|
||||
|
||||
/**
|
||||
* Returns the maximal time a operation on the underlying socket may block.
|
||||
*/
|
||||
int getSoTimeout();
|
||||
}
|
Loading…
Reference in New Issue
Block a user