Move IovArray handling code in an extra class to better seperate it and (#10559)
easier to test. Motivation: We should move the IovArray related code to an extra class so its easier to test Modifications: - Move into extra class - Add dedicated test Result: Cleanup
This commit is contained in:
parent
dd63d1c8d0
commit
d933a9dd56
@ -48,8 +48,7 @@ final class IOUringEventLoop extends SingleThreadEventLoop implements
|
|||||||
private final AtomicLong nextWakeupNanos = new AtomicLong(AWAKE);
|
private final AtomicLong nextWakeupNanos = new AtomicLong(AWAKE);
|
||||||
private final FileDescriptor eventfd;
|
private final FileDescriptor eventfd;
|
||||||
|
|
||||||
private final IovArray[] iovArrays;
|
private final IovArrays iovArrays;
|
||||||
private int iovArrayIdx;
|
|
||||||
|
|
||||||
private long prevDeadlineNanos = NONE;
|
private long prevDeadlineNanos = NONE;
|
||||||
private boolean pendingWakeup;
|
private boolean pendingWakeup;
|
||||||
@ -61,15 +60,12 @@ final class IOUringEventLoop extends SingleThreadEventLoop implements
|
|||||||
|
|
||||||
// TODO: Let's hard code this to 8 IovArrays to keep the memory overhead kind of small. We may want to consider
|
// TODO: Let's hard code this to 8 IovArrays to keep the memory overhead kind of small. We may want to consider
|
||||||
// allow to change this in the future.
|
// allow to change this in the future.
|
||||||
iovArrays = new IovArray[8];
|
iovArrays = new IovArrays(8);
|
||||||
for (int i = 0; i < iovArrays.length; i++) {
|
|
||||||
iovArrays[i] = new IovArray();
|
|
||||||
}
|
|
||||||
ringBuffer = Native.createRingBuffer(new Runnable() {
|
ringBuffer = Native.createRingBuffer(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
// Once we submitted its safe to clear the IovArrays and so be able to re-use these.
|
// Once we submitted its safe to clear the IovArrays and so be able to re-use these.
|
||||||
clearUsedIovArrays();
|
iovArrays.clear();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -183,13 +179,6 @@ final class IOUringEventLoop extends SingleThreadEventLoop implements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void clearUsedIovArrays() {
|
|
||||||
for (int i = 0; i <= iovArrayIdx; i++) {
|
|
||||||
iovArrays[i].clear();
|
|
||||||
}
|
|
||||||
iovArrayIdx = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean handle(int fd, int res, long flags, int op, int pollMask) {
|
public boolean handle(int fd, int res, long flags, int op, int pollMask) {
|
||||||
IOUringSubmissionQueue submissionQueue = ringBuffer.getIoUringSubmissionQueue();
|
IOUringSubmissionQueue submissionQueue = ringBuffer.getIoUringSubmissionQueue();
|
||||||
@ -294,9 +283,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();
|
||||||
for (IovArray array: iovArrays) {
|
iovArrays.release();
|
||||||
array.release();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public RingBuffer getRingBuffer() {
|
public RingBuffer getRingBuffer() {
|
||||||
@ -312,18 +299,11 @@ final class IOUringEventLoop extends SingleThreadEventLoop implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
public IovArray iovArray() {
|
public IovArray iovArray() {
|
||||||
IovArray iovArray = iovArrays[iovArrayIdx];
|
IovArray iovArray = iovArrays.next();
|
||||||
if (iovArray.isFull()) {
|
if (iovArray == null) {
|
||||||
if (iovArrayIdx < iovArrays.length - 1) {
|
ringBuffer.getIoUringSubmissionQueue().submit();
|
||||||
// There is another array left that we can use, increment the index and use it.
|
iovArray = iovArrays.next();
|
||||||
iovArrayIdx++;
|
assert iovArray != null;
|
||||||
iovArray = iovArrays[iovArrayIdx];
|
|
||||||
} else {
|
|
||||||
// No array left to use. Submit so we can reuse all of the arrays.
|
|
||||||
ringBuffer.getIoUringSubmissionQueue().submit();
|
|
||||||
iovArray = iovArrays[iovArrayIdx];
|
|
||||||
}
|
|
||||||
assert !iovArray.isFull();
|
|
||||||
}
|
}
|
||||||
return iovArray;
|
return iovArray;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 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.uring;
|
||||||
|
|
||||||
|
import io.netty.channel.unix.IovArray;
|
||||||
|
|
||||||
|
final class IovArrays {
|
||||||
|
|
||||||
|
private final IovArray[] iovArrays;
|
||||||
|
private int iovArrayIdx;
|
||||||
|
|
||||||
|
IovArrays(int numArrays) {
|
||||||
|
iovArrays = new IovArray[numArrays];
|
||||||
|
for (int i = 0 ; i < iovArrays.length; i++) {
|
||||||
|
iovArrays[i] = new IovArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the next {@link IovArray} to use which has space left in it. Otherwise returns {@code null} if there
|
||||||
|
* is no {@link IovArray} which has some space left.
|
||||||
|
*/
|
||||||
|
IovArray next() {
|
||||||
|
IovArray iovArray = iovArrays[iovArrayIdx];
|
||||||
|
if (iovArray.isFull()) {
|
||||||
|
if (iovArrayIdx < iovArrays.length - 1) {
|
||||||
|
// There is another array left that we can use, increment the index and use it.
|
||||||
|
iovArrayIdx++;
|
||||||
|
iovArray = iovArrays[iovArrayIdx];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return iovArray.isFull() ? null : iovArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear all {@link IovArray}s that were used since the last time this method was called.
|
||||||
|
*/
|
||||||
|
void clear() {
|
||||||
|
for (int i = 0; i <= iovArrayIdx; i++) {
|
||||||
|
iovArrays[i].clear();
|
||||||
|
}
|
||||||
|
iovArrayIdx = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void release() {
|
||||||
|
for (IovArray array: iovArrays) {
|
||||||
|
array.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 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.uring;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.buffer.Unpooled;
|
||||||
|
import io.netty.channel.unix.IovArray;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.assertNotSame;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
|
import static org.junit.Assert.assertSame;
|
||||||
|
|
||||||
|
public class IovArraysTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
IOUring.ensureAvailability();
|
||||||
|
ByteBuf buf = Unpooled.directBuffer(1).writeZero(1);
|
||||||
|
IovArrays arrays = new IovArrays(2);
|
||||||
|
try {
|
||||||
|
IovArray next = arrays.next();
|
||||||
|
assertNotNull(next);
|
||||||
|
assertSame(next, arrays.next());
|
||||||
|
|
||||||
|
while (next.add(buf, 0, buf.readableBytes())) {
|
||||||
|
// loop until we filled it.
|
||||||
|
}
|
||||||
|
|
||||||
|
IovArray next2 = arrays.next();
|
||||||
|
assertNotSame(next, next2);
|
||||||
|
|
||||||
|
while (next2.add(buf, 0, buf.readableBytes())) {
|
||||||
|
// loop until we filled it.
|
||||||
|
}
|
||||||
|
|
||||||
|
assertNull(arrays.next());
|
||||||
|
|
||||||
|
arrays.clear();
|
||||||
|
|
||||||
|
// We should start again from idx 0
|
||||||
|
assertSame(next, arrays.next());
|
||||||
|
} finally {
|
||||||
|
arrays.release();
|
||||||
|
buf.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user