@@ -241,13 +241,6 @@ public Runnable start(Listener transportListener) {
241
241
b .channelFactory (channelFactory );
242
242
// For non-socket based channel, the option will be ignored.
243
243
b .option (SO_KEEPALIVE , true );
244
- // For non-epoll based channel, the option will be ignored.
245
- if (keepAliveTimeNanos != KEEPALIVE_TIME_NANOS_DISABLED ) {
246
- ChannelOption <Integer > tcpUserTimeout = Utils .maybeGetTcpUserTimeoutOption ();
247
- if (tcpUserTimeout != null ) {
248
- b .option (tcpUserTimeout , (int ) TimeUnit .NANOSECONDS .toMillis (keepAliveTimeoutNanos ));
249
- }
250
- }
251
244
for (Map .Entry <ChannelOption <?>, ?> entry : channelOptions .entrySet ()) {
252
245
// Every entry in the map is obtained from
253
246
// NettyChannelBuilder#withOption(ChannelOption<T> option, T value)
@@ -286,6 +279,20 @@ public void run() {
286
279
};
287
280
}
288
281
channel = regFuture .channel ();
282
+ // For non-epoll based channel, the option will be ignored.
283
+ try {
284
+ if (keepAliveTimeNanos != KEEPALIVE_TIME_NANOS_DISABLED
285
+ && Class .forName ("io.netty.channel.epoll.AbstractEpollChannel" ).isInstance (channel )) {
286
+ ChannelOption <Integer > tcpUserTimeout = Utils .maybeGetTcpUserTimeoutOption ();
287
+ if (tcpUserTimeout != null ) {
288
+ int tcpUserTimeoutMs = (int ) TimeUnit .NANOSECONDS .toMillis (keepAliveTimeoutNanos );
289
+ channel .config ().setOption (tcpUserTimeout , tcpUserTimeoutMs );
290
+ }
291
+ }
292
+ } catch (ClassNotFoundException ignored ) {
293
+ // JVM did not load AbstractEpollChannel, so the current channel will not be of epoll type,
294
+ // so there is no need to set TCP_USER_TIMEOUT
295
+ }
289
296
// Start the write queue as soon as the channel is constructed
290
297
handler .startWriteQueue (channel );
291
298
// This write will have no effect, yet it will only complete once the negotiationHandler
0 commit comments