Reuse the tick buffer when possible & avoid iteration

Signed-off-by: TheMode <themode@outlook.fr>
This commit is contained in:
TheMode 2021-09-22 23:24:22 +02:00
parent d5d4a97694
commit 68107c9a90

View File

@ -263,25 +263,34 @@ public class PlayerSocketConnection extends PlayerConnection {
@Override @Override
public void flush() { public void flush() {
boolean shouldDisconnect = false; try {
synchronized (bufferLock) { synchronized (bufferLock) {
final BinaryBuffer localBuffer = tickBuffer.getPlain(); final BinaryBuffer localBuffer = tickBuffer.getPlain();
if (localBuffer.readableBytes() == 0 && waitingBuffers.isEmpty()) return; final boolean emptyWaitingList = waitingBuffers.isEmpty();
if (localBuffer.readableBytes() == 0 && emptyWaitingList) return;
// Update tick buffer // Update tick buffer
try { try {
this.tickBuffer.setPlain(PooledBuffers.get()); // Encryption support
if (encrypted) { if (encrypted) {
final Cipher cipher = encryptCipher;
// Encrypt data first
ByteBuffer cipherInput = localBuffer.asByteBuffer(0, localBuffer.writerOffset()); ByteBuffer cipherInput = localBuffer.asByteBuffer(0, localBuffer.writerOffset());
try { try {
cipher.update(cipherInput, cipherInput.duplicate()); this.encryptCipher.update(cipherInput, cipherInput.duplicate());
} catch (ShortBufferException e) { } catch (ShortBufferException e) {
MinecraftServer.getExceptionManager().handleException(e); MinecraftServer.getExceptionManager().handleException(e);
} }
} }
try {
// Try to write the current buffer
if (emptyWaitingList && localBuffer.writeChannel(channel)) {
// Can reuse buffer
localBuffer.clear();
return;
}
this.tickBuffer.setPlain(PooledBuffers.get());
this.waitingBuffers.add(localBuffer); this.waitingBuffers.add(localBuffer);
if (emptyWaitingList) return;
// Write as much as possible from the waiting list
Iterator<BinaryBuffer> iterator = waitingBuffers.iterator(); Iterator<BinaryBuffer> iterator = waitingBuffers.iterator();
while (iterator.hasNext()) { while (iterator.hasNext()) {
BinaryBuffer waitingBuffer = iterator.next(); BinaryBuffer waitingBuffer = iterator.next();
@ -289,20 +298,25 @@ public class PlayerSocketConnection extends PlayerConnection {
if (!waitingBuffer.writeChannel(channel)) break; if (!waitingBuffer.writeChannel(channel)) break;
iterator.remove(); iterator.remove();
PooledBuffers.add(waitingBuffer); PooledBuffers.add(waitingBuffer);
} catch (ClosedChannelException e) {
shouldDisconnect = true;
} catch (IOException e) { } catch (IOException e) {
MinecraftServer.getExceptionManager().handleException(e); MinecraftServer.getExceptionManager().handleException(e);
shouldDisconnect = true; throw new ClosedChannelException();
} }
} }
} catch (IOException e) {
MinecraftServer.getExceptionManager().handleException(e);
throw new ClosedChannelException();
}
} catch (OutOfMemoryError e) { } catch (OutOfMemoryError e) {
this.waitingBuffers.clear(); this.waitingBuffers.clear();
System.gc(); // Explicit gc forcing buffers to be collected System.gc(); // Explicit gc forcing buffers to be collected
shouldDisconnect = true; throw new ClosedChannelException();
} }
} }
if (shouldDisconnect) disconnect(); } catch (ClosedChannelException e) {
disconnect();
}
} }
@Override @Override