![JAR search and dependency download from the Maven repository](/logo.png)
org.glowroot.shaded.netty.channel.epoll.EpollSocketChannel Maven / Gradle / Ivy
The newest version!
/*
* Copyright 2014 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 org.glowroot.shaded.netty.channel.epoll;
import org.glowroot.shaded.netty.channel.Channel;
import org.glowroot.shaded.netty.channel.ChannelFuture;
import org.glowroot.shaded.netty.channel.ChannelPromise;
import org.glowroot.shaded.netty.channel.EventLoop;
import org.glowroot.shaded.netty.channel.socket.ServerSocketChannel;
import org.glowroot.shaded.netty.channel.socket.SocketChannel;
import org.glowroot.shaded.netty.channel.unix.FileDescriptor;
import org.glowroot.shaded.netty.util.concurrent.GlobalEventExecutor;
import org.glowroot.shaded.netty.util.internal.OneTimeTask;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.concurrent.Executor;
/**
* {@link SocketChannel} implementation that uses linux EPOLL Edge-Triggered Mode for
* maximal performance.
*/
public final class EpollSocketChannel extends AbstractEpollStreamChannel implements SocketChannel {
private final EpollSocketChannelConfig config;
private volatile InetSocketAddress local;
private volatile InetSocketAddress remote;
EpollSocketChannel(Channel parent, int fd, InetSocketAddress remote) {
super(parent, fd);
config = new EpollSocketChannelConfig(this);
// Directly cache the remote and local addresses
// See https://github.com/netty/netty/issues/2359
this.remote = remote;
local = Native.localAddress(fd);
}
public EpollSocketChannel() {
super(Native.socketStreamFd());
config = new EpollSocketChannelConfig(this);
}
/**
* Creates a new {@link EpollSocketChannel} from an existing {@link FileDescriptor}.
*/
public EpollSocketChannel(FileDescriptor fd) {
super(fd);
config = new EpollSocketChannelConfig(this);
// As we create an EpollSocketChannel from a FileDescriptor we should try to obtain the remote and local
// address from it. This is needed as the FileDescriptor may be bound/connected already.
remote = Native.remoteAddress(fd.intValue());
local = Native.localAddress(fd.intValue());
}
/**
* Returns the {@code TCP_INFO} for the current socket. See man 7 tcp.
*/
public EpollTcpInfo tcpInfo() {
return tcpInfo(new EpollTcpInfo());
}
/**
* Updates and returns the {@code TCP_INFO} for the current socket.
* See man 7 tcp.
*/
public EpollTcpInfo tcpInfo(EpollTcpInfo info) {
Native.tcpInfo(fd().intValue(), info);
return info;
}
@Override
public InetSocketAddress remoteAddress() {
return (InetSocketAddress) super.remoteAddress();
}
@Override
public InetSocketAddress localAddress() {
return (InetSocketAddress) super.localAddress();
}
@Override
protected SocketAddress localAddress0() {
return local;
}
@Override
protected SocketAddress remoteAddress0() {
if (remote == null) {
// Remote address not know, try to get it now.
InetSocketAddress address = Native.remoteAddress(fd().intValue());
if (address != null) {
remote = address;
}
return address;
}
return remote;
}
@Override
protected void doBind(SocketAddress local) throws Exception {
InetSocketAddress localAddress = (InetSocketAddress) local;
int fd = fd().intValue();
Native.bind(fd, localAddress);
this.local = Native.localAddress(fd);
}
@Override
public EpollSocketChannelConfig config() {
return config;
}
@Override
public boolean isInputShutdown() {
return isInputShutdown0();
}
@Override
public boolean isOutputShutdown() {
return isOutputShutdown0();
}
@Override
public ChannelFuture shutdownOutput() {
return shutdownOutput(newPromise());
}
@Override
public ChannelFuture shutdownOutput(final ChannelPromise promise) {
Executor closeExecutor = ((EpollSocketChannelUnsafe) unsafe()).closeExecutor();
if (closeExecutor != null) {
closeExecutor.execute(new OneTimeTask() {
@Override
public void run() {
shutdownOutput0(promise);
}
});
} else {
EventLoop loop = eventLoop();
if (loop.inEventLoop()) {
shutdownOutput0(promise);
} else {
loop.execute(new OneTimeTask() {
@Override
public void run() {
shutdownOutput0(promise);
}
});
}
}
return promise;
}
@Override
public ServerSocketChannel parent() {
return (ServerSocketChannel) super.parent();
}
@Override
protected AbstractEpollUnsafe newUnsafe() {
return new EpollSocketChannelUnsafe();
}
@Override
protected boolean doConnect(SocketAddress remoteAddress, SocketAddress localAddress) throws Exception {
if (localAddress != null) {
checkResolvable((InetSocketAddress) localAddress);
}
checkResolvable((InetSocketAddress) remoteAddress);
int fd = fd().intValue();
boolean connected = super.doConnect(remoteAddress, localAddress);
if (connected) {
remote = (InetSocketAddress) remoteAddress;
return true;
}
// We always need to set the localAddress even if not connected yet
//
// See https://github.com/netty/netty/issues/3463
local = Native.localAddress(fd);
return connected;
}
private final class EpollSocketChannelUnsafe extends EpollStreamUnsafe {
@Override
protected Executor closeExecutor() {
if (config().getSoLinger() > 0) {
return GlobalEventExecutor.INSTANCE;
}
return null;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy