This commit is contained in:
Norman Maurer 2020-09-07 15:42:28 +02:00
parent ddb503f76d
commit 381493999d
4 changed files with 32 additions and 26 deletions

View File

@ -37,6 +37,7 @@ import io.netty.channel.socket.SocketChannelConfig;
import io.netty.channel.unix.Buffer; import io.netty.channel.unix.Buffer;
import io.netty.channel.unix.Errors; import io.netty.channel.unix.Errors;
import io.netty.channel.unix.FileDescriptor; import io.netty.channel.unix.FileDescriptor;
import io.netty.channel.unix.IovArray;
import io.netty.channel.unix.NativeInetAddress; import io.netty.channel.unix.NativeInetAddress;
import io.netty.channel.unix.Socket; import io.netty.channel.unix.Socket;
import io.netty.channel.unix.UnixChannel; import io.netty.channel.unix.UnixChannel;
@ -89,9 +90,6 @@ abstract class AbstractIOUringChannel extends AbstractChannel implements UnixCha
private volatile SocketAddress local; private volatile SocketAddress local;
private volatile SocketAddress remote; private volatile SocketAddress remote;
//to release it
private long iovecMemoryAddress = -1;
AbstractIOUringChannel(final Channel parent, LinuxSocket socket) { AbstractIOUringChannel(final Channel parent, LinuxSocket socket) {
super(parent); super(parent);
this.socket = checkNotNull(socket, "fd"); this.socket = checkNotNull(socket, "fd");
@ -305,25 +303,30 @@ abstract class AbstractIOUringChannel extends AbstractChannel implements UnixCha
private void doWriteMultiple(ChannelOutboundBuffer in) { private void doWriteMultiple(ChannelOutboundBuffer in) {
final IovecArrayPool iovecArray = ((IOUringEventLoop) eventLoop()).getIovecArrayPool(); final IovArray iovecArray = ((IOUringEventLoop) eventLoop()).getIovArray();
int offset = iovecArray.count();
try {
in.forEachFlushedMessage(iovecArray);
iovecMemoryAddress = iovecArray.createNewIovecMemoryAddress(); int count = iovecArray.count() - offset;
if (iovecMemoryAddress != -1) { if (count > 0) {
try { submissionQueue().addWritev(socket.intValue(), iovecArray.memoryAddress(offset), count);
in.forEachFlushedMessage(iovecArray); submissionQueue().submit();
} catch (Exception e) {
// This should never happem, anyway fallback to single write.
doWriteSingle((ByteBuf) in.current());
}
if (iovecArray.count() > 0) {
submissionQueue().addWritev(socket.intValue(), iovecMemoryAddress, iovecArray.count());
ioState |= WRITE_SCHEDULED; ioState |= WRITE_SCHEDULED;
if (iovecArray.isFull()) {
submissionQueue().submit();
iovecArray.clear();
}
} else {
in.removeBytes(0);
} }
} else { } catch (Exception e) {
// We were not be able to create a new iovec, fallback to single write. e.printStackTrace();
// This should never happem, anyway fallback to single write.
doWriteSingle((ByteBuf) in.current()); doWriteSingle((ByteBuf) in.current());
} }
} }
protected final void doWriteSingle(ByteBuf buf) { protected final void doWriteSingle(ByteBuf buf) {
@ -545,10 +548,6 @@ abstract class AbstractIOUringChannel extends AbstractChannel implements UnixCha
ioState &= ~WRITE_SCHEDULED; ioState &= ~WRITE_SCHEDULED;
ChannelOutboundBuffer channelOutboundBuffer = unsafe().outboundBuffer(); ChannelOutboundBuffer channelOutboundBuffer = unsafe().outboundBuffer();
if (iovecMemoryAddress != -1) {
((IOUringEventLoop) eventLoop()).getIovecArrayPool().releaseIovec(iovecMemoryAddress);
iovecMemoryAddress = -1;
}
if (res >= 0) { if (res >= 0) {
channelOutboundBuffer.removeBytes(res); channelOutboundBuffer.removeBytes(res);
doWrite(channelOutboundBuffer); doWrite(channelOutboundBuffer);

View File

@ -19,6 +19,7 @@ import io.netty.channel.EventLoopGroup;
import io.netty.channel.SingleThreadEventLoop; import io.netty.channel.SingleThreadEventLoop;
import io.netty.channel.unix.Errors; import io.netty.channel.unix.Errors;
import io.netty.channel.unix.FileDescriptor; import io.netty.channel.unix.FileDescriptor;
import io.netty.channel.unix.IovArray;
import io.netty.util.collection.IntObjectHashMap; import io.netty.util.collection.IntObjectHashMap;
import io.netty.util.collection.IntObjectMap; import io.netty.util.collection.IntObjectMap;
import io.netty.util.internal.PlatformDependent; import io.netty.util.internal.PlatformDependent;
@ -46,7 +47,7 @@ final class IOUringEventLoop extends SingleThreadEventLoop implements
// other value T when EL is waiting with wakeup scheduled at time T // other value T when EL is waiting with wakeup scheduled at time T
private final AtomicLong nextWakeupNanos = new AtomicLong(AWAKE); private final AtomicLong nextWakeupNanos = new AtomicLong(AWAKE);
private final FileDescriptor eventfd; private final FileDescriptor eventfd;
private final IovecArrayPool iovecArrayPool; private final IovArray iovArray;
private long prevDeadlineNanos = NONE; private long prevDeadlineNanos = NONE;
private boolean pendingWakeup; private boolean pendingWakeup;
@ -57,7 +58,7 @@ final class IOUringEventLoop extends SingleThreadEventLoop implements
ringBuffer = Native.createRingBuffer(); ringBuffer = Native.createRingBuffer();
eventfd = Native.newEventFd(); eventfd = Native.newEventFd();
logger.trace("New EventLoop: {}", this.toString()); logger.trace("New EventLoop: {}", this.toString());
iovecArrayPool = new IovecArrayPool(); iovArray = new IovArray();
} }
@Override @Override
@ -151,10 +152,12 @@ final class IOUringEventLoop extends SingleThreadEventLoop implements
runAllTasks(); runAllTasks();
submissionQueue.submit(); submissionQueue.submit();
iovArray.clear();
try { try {
if (isShuttingDown()) { if (isShuttingDown()) {
closeAll(); closeAll();
submissionQueue.submit(); submissionQueue.submit();
iovArray.clear();
if (confirmShutdown()) { if (confirmShutdown()) {
break; break;
} }
@ -253,7 +256,7 @@ final class IOUringEventLoop extends SingleThreadEventLoop implements
logger.warn("Failed to close the event fd.", e); logger.warn("Failed to close the event fd.", e);
} }
ringBuffer.close(); ringBuffer.close();
iovecArrayPool.release(); iovArray.release();
} }
public RingBuffer getRingBuffer() { public RingBuffer getRingBuffer() {
@ -268,7 +271,7 @@ final class IOUringEventLoop extends SingleThreadEventLoop implements
} }
} }
public IovecArrayPool getIovecArrayPool() { public IovArray getIovArray() {
return iovecArrayPool; return iovArray;
} }
} }

View File

@ -153,6 +153,10 @@ public final class IovArray implements MessageProcessor {
return true; return true;
} }
public boolean isFull() {
return count >= IOV_SIZE || size >= maxBytes;
}
/** /**
* Returns the number if iov entries. * Returns the number if iov entries.
*/ */

View File

@ -336,7 +336,7 @@ public final class ChannelOutboundBuffer {
for (;;) { for (;;) {
Object msg = current(); Object msg = current();
if (!(msg instanceof ByteBuf)) { if (!(msg instanceof ByteBuf)) {
assert writtenBytes == 0; assert writtenBytes == 0 : "writtenBytes: " + writtenBytes;
break; break;
} }