use of io.netty.buffer.ByteBufAllocator in project netty by netty.
the class NioSctpChannel method doWriteMessage.
@Override
protected boolean doWriteMessage(Object msg, ChannelOutboundBuffer in) throws Exception {
SctpMessage packet = (SctpMessage) msg;
ByteBuf data = packet.content();
int dataLen = data.readableBytes();
if (dataLen == 0) {
return true;
}
ByteBufAllocator alloc = alloc();
boolean needsCopy = data.nioBufferCount() != 1;
if (!needsCopy) {
if (!data.isDirect() && alloc.isDirectBufferPooled()) {
needsCopy = true;
}
}
ByteBuffer nioData;
if (needsCopy) {
data = alloc.directBuffer(dataLen).writeBytes(data);
}
nioData = data.nioBuffer();
final MessageInfo mi = MessageInfo.createOutgoing(association(), null, packet.streamIdentifier());
mi.payloadProtocolID(packet.protocolIdentifier());
mi.streamNumber(packet.streamIdentifier());
mi.unordered(packet.isUnordered());
final int writtenBytes = javaChannel().send(nioData, mi);
return writtenBytes > 0;
}
use of io.netty.buffer.ByteBufAllocator in project netty by netty.
the class AbstractEpollChannel method newDirectBuffer.
/**
* Returns an off-heap copy of the specified {@link ByteBuf}, and releases the specified holder.
* The caller must ensure that the holder releases the original {@link ByteBuf} when the holder is released by
* this method.
*/
protected final ByteBuf newDirectBuffer(Object holder, ByteBuf buf) {
final int readableBytes = buf.readableBytes();
if (readableBytes == 0) {
ReferenceCountUtil.release(holder);
return Unpooled.EMPTY_BUFFER;
}
final ByteBufAllocator alloc = alloc();
if (alloc.isDirectBufferPooled()) {
return newDirectBuffer0(holder, buf, alloc, readableBytes);
}
final ByteBuf directBuf = ByteBufUtil.threadLocalDirectBuffer();
if (directBuf == null) {
return newDirectBuffer0(holder, buf, alloc, readableBytes);
}
directBuf.writeBytes(buf, buf.readerIndex(), readableBytes);
ReferenceCountUtil.safeRelease(holder);
return directBuf;
}
use of io.netty.buffer.ByteBufAllocator in project netty by netty.
the class AbstractTestsuiteTest method run.
protected void run(TestInfo testInfo, Runner<T> runner) throws Throwable {
List<TestsuitePermutation.BootstrapFactory<T>> combos = newFactories();
String methodName = TestUtils.testMethodName(testInfo);
for (ByteBufAllocator allocator : newAllocators()) {
int i = 0;
for (TestsuitePermutation.BootstrapFactory<T> e : combos) {
cb = e.newInstance();
configure(cb, allocator);
logger.info(String.format("Running: %s %d of %d with %s", methodName, ++i, combos.size(), StringUtil.simpleClassName(allocator)));
runner.run(cb);
}
}
}
use of io.netty.buffer.ByteBufAllocator in project netty by netty.
the class SslHandler method wrap.
// This method will not call setHandshakeFailure(...) !
private void wrap(ChannelHandlerContext ctx, boolean inUnwrap) throws SSLException {
ByteBuf out = null;
ByteBufAllocator alloc = ctx.alloc();
try {
final int wrapDataSize = this.wrapDataSize;
// See https://github.com/netty/netty/issues/5860
outer: while (!ctx.isRemoved()) {
ChannelPromise promise = ctx.newPromise();
ByteBuf buf = wrapDataSize > 0 ? pendingUnencryptedWrites.remove(alloc, wrapDataSize, promise) : pendingUnencryptedWrites.removeFirst(promise);
if (buf == null) {
break;
}
if (out == null) {
out = allocateOutNetBuf(ctx, buf.readableBytes(), buf.nioBufferCount());
}
SSLEngineResult result = wrap(alloc, engine, buf, out);
if (buf.isReadable()) {
pendingUnencryptedWrites.addFirst(buf, promise);
// When we add the buffer/promise pair back we need to be sure we don't complete the promise
// later. We only complete the promise if the buffer is completely consumed.
promise = null;
} else {
buf.release();
}
// writes may occur out of order and TLS sequencing may be off (e.g. SSLV3_ALERT_BAD_RECORD_MAC).
if (out.isReadable()) {
final ByteBuf b = out;
out = null;
if (promise != null) {
ctx.write(b, promise);
} else {
ctx.write(b);
}
} else if (promise != null) {
ctx.write(Unpooled.EMPTY_BUFFER, promise);
}
if (result.getStatus() == Status.CLOSED) {
// Make a best effort to preserve any exception that way previously encountered from the handshake
// or the transport, else fallback to a general error.
Throwable exception = handshakePromise.cause();
if (exception == null) {
exception = sslClosePromise.cause();
if (exception == null) {
exception = new SslClosedEngineException("SSLEngine closed already");
}
}
pendingUnencryptedWrites.releaseAndFailAll(ctx, exception);
return;
} else {
switch(result.getHandshakeStatus()) {
case NEED_TASK:
if (!runDelegatedTasks(inUnwrap)) {
// resume once the task completes.
break outer;
}
break;
case FINISHED:
case // work around for android bug that skips the FINISHED state.
NOT_HANDSHAKING:
setHandshakeSuccess();
break;
case NEED_WRAP:
// consumed by the remote peer.
if (result.bytesProduced() > 0 && pendingUnencryptedWrites.isEmpty()) {
pendingUnencryptedWrites.add(Unpooled.EMPTY_BUFFER);
}
break;
case NEED_UNWRAP:
// The underlying engine is starving so we need to feed it with more data.
// See https://github.com/netty/netty/pull/5039
readIfNeeded(ctx);
return;
default:
throw new IllegalStateException("Unknown handshake status: " + result.getHandshakeStatus());
}
}
}
} finally {
if (out != null) {
out.release();
}
if (inUnwrap) {
setState(STATE_NEEDS_FLUSH);
}
}
}
use of io.netty.buffer.ByteBufAllocator in project netty by netty.
the class AbstractOioByteChannel method doRead.
@Override
protected void doRead() {
final ChannelConfig config = config();
if (isInputShutdown() || !readPending) {
// during the same read loop readPending was set to false.
return;
}
// In OIO we should set readPending to false even if the read was not successful so we can schedule
// another read on the event loop if no reads are done.
readPending = false;
final ChannelPipeline pipeline = pipeline();
final ByteBufAllocator allocator = config.getAllocator();
final RecvByteBufAllocator.Handle allocHandle = unsafe().recvBufAllocHandle();
allocHandle.reset(config);
ByteBuf byteBuf = null;
boolean close = false;
boolean readData = false;
try {
byteBuf = allocHandle.allocate(allocator);
do {
allocHandle.lastBytesRead(doReadBytes(byteBuf));
if (allocHandle.lastBytesRead() <= 0) {
if (!byteBuf.isReadable()) {
// nothing was read. release the buffer.
byteBuf.release();
byteBuf = null;
close = allocHandle.lastBytesRead() < 0;
if (close) {
// There is nothing left to read as we received an EOF.
readPending = false;
}
}
break;
} else {
readData = true;
}
final int available = available();
if (available <= 0) {
break;
}
// Oio collects consecutive read operations into 1 ByteBuf before propagating up the pipeline.
if (!byteBuf.isWritable()) {
final int capacity = byteBuf.capacity();
final int maxCapacity = byteBuf.maxCapacity();
if (capacity == maxCapacity) {
allocHandle.incMessagesRead(1);
readPending = false;
pipeline.fireChannelRead(byteBuf);
byteBuf = allocHandle.allocate(allocator);
} else {
final int writerIndex = byteBuf.writerIndex();
if (writerIndex + available > maxCapacity) {
byteBuf.capacity(maxCapacity);
} else {
byteBuf.ensureWritable(available);
}
}
}
} while (allocHandle.continueReading());
if (byteBuf != null) {
// it because allocHandle.continueReading() returned false.
if (byteBuf.isReadable()) {
readPending = false;
pipeline.fireChannelRead(byteBuf);
} else {
byteBuf.release();
}
byteBuf = null;
}
if (readData) {
allocHandle.readComplete();
pipeline.fireChannelReadComplete();
}
if (close) {
closeOnRead(pipeline);
}
} catch (Throwable t) {
handleReadException(pipeline, byteBuf, t, close, allocHandle);
} finally {
if (readPending || config.isAutoRead() || !readData && isActive()) {
// Reading 0 bytes could mean there is a SocketTimeout and no data was actually read, so we
// should execute read() again because no data may have been read.
read();
}
}
}
Aggregations