Search in sources :

Example 21 with PooledByteBuffer

use of io.undertow.connector.PooledByteBuffer in project undertow by undertow-io.

the class BlockingSenderImpl method writeBuffer.

private boolean writeBuffer(final ByteBuffer[] buffers, final IoCallback callback) {
    if (outputStream instanceof BufferWritableOutputStream) {
        //fast path, if the stream can take a buffer directly just write to it
        try {
            ((BufferWritableOutputStream) outputStream).write(buffers);
            return true;
        } catch (IOException e) {
            callback.onException(exchange, this, e);
            return false;
        }
    }
    for (ByteBuffer buffer : buffers) {
        if (buffer.hasArray()) {
            try {
                outputStream.write(buffer.array(), buffer.arrayOffset(), buffer.remaining());
            } catch (IOException e) {
                callback.onException(exchange, this, e);
                return false;
            }
        } else {
            try (PooledByteBuffer pooled = exchange.getConnection().getByteBufferPool().getArrayBackedPool().allocate()) {
                while (buffer.hasRemaining()) {
                    int toRead = Math.min(buffer.remaining(), pooled.getBuffer().remaining());
                    buffer.get(pooled.getBuffer().array(), pooled.getBuffer().arrayOffset(), toRead);
                    try {
                        outputStream.write(pooled.getBuffer().array(), pooled.getBuffer().arrayOffset(), toRead);
                    } catch (IOException e) {
                        callback.onException(exchange, this, e);
                        return false;
                    }
                }
            }
        }
    }
    return true;
}
Also used : PooledByteBuffer(io.undertow.connector.PooledByteBuffer) IOException(java.io.IOException) PooledByteBuffer(io.undertow.connector.PooledByteBuffer) ByteBuffer(java.nio.ByteBuffer)

Example 22 with PooledByteBuffer

use of io.undertow.connector.PooledByteBuffer in project undertow by undertow-io.

the class UndertowOutputStream method write.

/**
     * {@inheritDoc}
     */
public void write(final byte[] b, final int off, final int len) throws IOException {
    if (len < 1) {
        return;
    }
    if (Thread.currentThread() == exchange.getIoThread()) {
        throw UndertowMessages.MESSAGES.blockingIoFromIOThread();
    }
    if (anyAreSet(state, FLAG_CLOSED)) {
        throw UndertowMessages.MESSAGES.streamIsClosed();
    }
    //if this is the last of the content
    ByteBuffer buffer = buffer();
    if (len == contentLength - written || buffer.remaining() < len) {
        if (buffer.remaining() < len) {
            //so what we have will not fit.
            //We allocate multiple buffers up to MAX_BUFFERS_TO_ALLOCATE
            //and put it in them
            //if it still dopes not fit we loop, re-using these buffers
            StreamSinkChannel channel = this.channel;
            if (channel == null) {
                this.channel = channel = exchange.getResponseChannel();
            }
            final ByteBufferPool bufferPool = exchange.getConnection().getByteBufferPool();
            ByteBuffer[] buffers = new ByteBuffer[MAX_BUFFERS_TO_ALLOCATE + 1];
            PooledByteBuffer[] pooledBuffers = new PooledByteBuffer[MAX_BUFFERS_TO_ALLOCATE];
            try {
                buffers[0] = buffer;
                int bytesWritten = 0;
                int rem = buffer.remaining();
                buffer.put(b, bytesWritten + off, rem);
                buffer.flip();
                bytesWritten += rem;
                int bufferCount = 1;
                for (int i = 0; i < MAX_BUFFERS_TO_ALLOCATE; ++i) {
                    PooledByteBuffer pooled = bufferPool.allocate();
                    pooledBuffers[bufferCount - 1] = pooled;
                    buffers[bufferCount++] = pooled.getBuffer();
                    ByteBuffer cb = pooled.getBuffer();
                    int toWrite = len - bytesWritten;
                    if (toWrite > cb.remaining()) {
                        rem = cb.remaining();
                        cb.put(b, bytesWritten + off, rem);
                        cb.flip();
                        bytesWritten += rem;
                    } else {
                        cb.put(b, bytesWritten + off, len - bytesWritten);
                        bytesWritten = len;
                        cb.flip();
                        break;
                    }
                }
                Channels.writeBlocking(channel, buffers, 0, bufferCount);
                while (bytesWritten < len) {
                    //ok, it did not fit, loop and loop and loop until it is done
                    bufferCount = 0;
                    for (int i = 0; i < MAX_BUFFERS_TO_ALLOCATE + 1; ++i) {
                        ByteBuffer cb = buffers[i];
                        cb.clear();
                        bufferCount++;
                        int toWrite = len - bytesWritten;
                        if (toWrite > cb.remaining()) {
                            rem = cb.remaining();
                            cb.put(b, bytesWritten + off, rem);
                            cb.flip();
                            bytesWritten += rem;
                        } else {
                            cb.put(b, bytesWritten + off, len - bytesWritten);
                            bytesWritten = len;
                            cb.flip();
                            break;
                        }
                    }
                    Channels.writeBlocking(channel, buffers, 0, bufferCount);
                }
                buffer.clear();
            } finally {
                for (int i = 0; i < pooledBuffers.length; ++i) {
                    PooledByteBuffer p = pooledBuffers[i];
                    if (p == null) {
                        break;
                    }
                    p.close();
                }
            }
        } else {
            buffer.put(b, off, len);
            if (buffer.remaining() == 0) {
                writeBufferBlocking(false);
            }
        }
    } else {
        buffer.put(b, off, len);
        if (buffer.remaining() == 0) {
            writeBufferBlocking(false);
        }
    }
    updateWritten(len);
}
Also used : ByteBufferPool(io.undertow.connector.ByteBufferPool) PooledByteBuffer(io.undertow.connector.PooledByteBuffer) StreamSinkChannel(org.xnio.channels.StreamSinkChannel) ByteBuffer(java.nio.ByteBuffer) PooledByteBuffer(io.undertow.connector.PooledByteBuffer)

Example 23 with PooledByteBuffer

use of io.undertow.connector.PooledByteBuffer in project undertow by undertow-io.

the class Http2StreamSinkChannel method allocateAll.

protected PooledByteBuffer[] allocateAll(PooledByteBuffer[] allHeaderBuffers, PooledByteBuffer currentBuffer) {
    PooledByteBuffer[] ret;
    if (allHeaderBuffers == null) {
        ret = new PooledByteBuffer[2];
        ret[0] = currentBuffer;
        ret[1] = getChannel().getBufferPool().allocate();
        ByteBuffer newBuffer = ret[1].getBuffer();
        if (newBuffer.remaining() > getChannel().getSendMaxFrameSize()) {
            //make sure the buffers are not too large to go over the max frame size
            newBuffer.limit(newBuffer.position() + getChannel().getSendMaxFrameSize());
        }
    } else {
        ret = new PooledByteBuffer[allHeaderBuffers.length + 1];
        System.arraycopy(allHeaderBuffers, 0, ret, 0, allHeaderBuffers.length);
        ret[ret.length - 1] = getChannel().getBufferPool().allocate();
        ByteBuffer newBuffer = ret[ret.length - 1].getBuffer();
        if (newBuffer.remaining() > getChannel().getSendMaxFrameSize()) {
            newBuffer.limit(newBuffer.position() + getChannel().getSendMaxFrameSize());
        }
    }
    return ret;
}
Also used : PooledByteBuffer(io.undertow.connector.PooledByteBuffer) PooledByteBuffer(io.undertow.connector.PooledByteBuffer) ByteBuffer(java.nio.ByteBuffer)

Example 24 with PooledByteBuffer

use of io.undertow.connector.PooledByteBuffer in project undertow by undertow-io.

the class AbstractFramedStreamSourceChannel method beforeRead.

private void beforeRead() throws IOException {
    if (anyAreSet(state, STATE_STREAM_BROKEN)) {
        throw UndertowMessages.MESSAGES.channelIsClosed();
    }
    if (data == null) {
        synchronized (lock) {
            FrameData pending = pendingFrameData.poll();
            if (pending != null) {
                PooledByteBuffer frameData = pending.getFrameData();
                boolean hasData = true;
                if (!frameData.getBuffer().hasRemaining()) {
                    frameData.close();
                    hasData = false;
                }
                if (pending.getFrameHeaderData() != null) {
                    this.frameDataRemaining = pending.getFrameHeaderData().getFrameLength();
                    handleHeaderData(pending.getFrameHeaderData());
                }
                if (hasData) {
                    this.frameDataRemaining = updateFrameDataRemaining(frameData, frameDataRemaining);
                    this.currentDataOriginalSize = frameData.getBuffer().remaining();
                    try {
                        this.data = processFrameData(frameData, frameDataRemaining - currentDataOriginalSize == 0);
                    } catch (Exception e) {
                        frameData.close();
                        UndertowLogger.REQUEST_IO_LOGGER.ioException(new IOException(e));
                        markStreamBroken();
                    }
                }
            }
        }
    }
}
Also used : PooledByteBuffer(io.undertow.connector.PooledByteBuffer) IOException(java.io.IOException) InterruptedIOException(java.io.InterruptedIOException) IOException(java.io.IOException) InterruptedIOException(java.io.InterruptedIOException)

Example 25 with PooledByteBuffer

use of io.undertow.connector.PooledByteBuffer in project undertow by undertow-io.

the class HttpReadListener method handleHttp2PriorKnowledge.

private void handleHttp2PriorKnowledge(final StreamConnection connection, final HttpServerConnection serverConnection, PooledByteBuffer readData) throws IOException {
    final ConduitStreamSourceChannel request = connection.getSourceChannel();
    byte[] data = new byte[PRI_EXPECTED.length];
    final ByteBuffer buffer = ByteBuffer.wrap(data);
    if (readData.getBuffer().hasRemaining()) {
        while (readData.getBuffer().hasRemaining() && buffer.hasRemaining()) {
            buffer.put(readData.getBuffer().get());
        }
    }
    final PooledByteBuffer extraData;
    if (readData.getBuffer().hasRemaining()) {
        extraData = readData;
    } else {
        readData.close();
        extraData = null;
    }
    if (!doHttp2PriRead(connection, buffer, serverConnection, extraData)) {
        request.getReadSetter().set(new ChannelListener<StreamSourceChannel>() {

            @Override
            public void handleEvent(StreamSourceChannel channel) {
                try {
                    doHttp2PriRead(connection, buffer, serverConnection, extraData);
                } catch (IOException e) {
                    UndertowLogger.REQUEST_IO_LOGGER.ioException(e);
                    IoUtils.safeClose(connection);
                }
            }
        });
        request.resumeReads();
    }
}
Also used : StreamSourceChannel(org.xnio.channels.StreamSourceChannel) ConduitStreamSourceChannel(org.xnio.conduits.ConduitStreamSourceChannel) PooledByteBuffer(io.undertow.connector.PooledByteBuffer) IOException(java.io.IOException) ConduitStreamSourceChannel(org.xnio.conduits.ConduitStreamSourceChannel) ByteBuffer(java.nio.ByteBuffer) PooledByteBuffer(io.undertow.connector.PooledByteBuffer)

Aggregations

PooledByteBuffer (io.undertow.connector.PooledByteBuffer)54 ByteBuffer (java.nio.ByteBuffer)45 IOException (java.io.IOException)28 ImmediatePooledByteBuffer (io.undertow.util.ImmediatePooledByteBuffer)9 StreamSourceChannel (org.xnio.channels.StreamSourceChannel)8 HttpServerExchange (io.undertow.server.HttpServerExchange)7 ClosedChannelException (java.nio.channels.ClosedChannelException)6 ByteArrayOutputStream (java.io.ByteArrayOutputStream)5 ChannelListener (org.xnio.ChannelListener)5 HttpHandler (io.undertow.server.HttpHandler)4 StreamSinkChannel (org.xnio.channels.StreamSinkChannel)4 SendFrameHeader (io.undertow.server.protocol.framed.SendFrameHeader)3 HeaderMap (io.undertow.util.HeaderMap)3 HttpString (io.undertow.util.HttpString)3 InterruptedIOException (java.io.InterruptedIOException)3 ByteBufferPool (io.undertow.connector.ByteBufferPool)2 CharBuffer (java.nio.CharBuffer)2 CharsetDecoder (java.nio.charset.CharsetDecoder)2 IoCallback (io.undertow.io.IoCallback)1 Sender (io.undertow.io.Sender)1