Search in sources :

Example 1 with NioSocketWrapper

use of org.apache.tomcat.util.net.NioEndpoint.NioSocketWrapper in project tomcat by apache.

the class NioBlockingSelector method write.

/**
     * Performs a blocking write using the bytebuffer for data to be written
     * If the <code>selector</code> parameter is null, then it will perform a busy write that could
     * take up a lot of CPU cycles.
     * @param buf ByteBuffer - the buffer containing the data, we will write as long as <code>(buf.hasRemaining()==true)</code>
     * @param socket SocketChannel - the socket to write data to
     * @param writeTimeout long - the timeout for this write operation in milliseconds, -1 means no timeout
     * @return int - returns the number of bytes written
     * @throws EOFException if write returns -1
     * @throws SocketTimeoutException if the write times out
     * @throws IOException if an IO Exception occurs in the underlying socket logic
     */
public int write(ByteBuffer buf, NioChannel socket, long writeTimeout) throws IOException {
    SelectionKey key = socket.getIOChannel().keyFor(socket.getPoller().getSelector());
    if (key == null)
        throw new IOException("Key no longer registered");
    KeyReference reference = keyReferenceStack.pop();
    if (reference == null) {
        reference = new KeyReference();
    }
    NioSocketWrapper att = (NioSocketWrapper) key.attachment();
    int written = 0;
    boolean timedout = false;
    //assume we can write
    int keycount = 1;
    //start the timeout timer
    long time = System.currentTimeMillis();
    try {
        while ((!timedout) && buf.hasRemaining()) {
            if (keycount > 0) {
                //only write if we were registered for a write
                //write the data
                int cnt = socket.write(buf);
                if (cnt == -1)
                    throw new EOFException();
                written += cnt;
                if (cnt > 0) {
                    //reset our timeout timer
                    time = System.currentTimeMillis();
                    //we successfully wrote, try again without a selector
                    continue;
                }
            }
            try {
                if (att.getWriteLatch() == null || att.getWriteLatch().getCount() == 0)
                    att.startWriteLatch(1);
                poller.add(att, SelectionKey.OP_WRITE, reference);
                if (writeTimeout < 0) {
                    att.awaitWriteLatch(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
                } else {
                    att.awaitWriteLatch(writeTimeout, TimeUnit.MILLISECONDS);
                }
            } catch (InterruptedException ignore) {
            // Ignore
            }
            if (att.getWriteLatch() != null && att.getWriteLatch().getCount() > 0) {
                //we got interrupted, but we haven't received notification from the poller.
                keycount = 0;
            } else {
                //latch countdown has happened
                keycount = 1;
                att.resetWriteLatch();
            }
            if (writeTimeout > 0 && (keycount == 0))
                timedout = (System.currentTimeMillis() - time) >= writeTimeout;
        }
        //while
        if (timedout)
            throw new SocketTimeoutException();
    } finally {
        poller.remove(att, SelectionKey.OP_WRITE);
        if (timedout && reference.key != null) {
            poller.cancelKey(reference.key);
        }
        reference.key = null;
        keyReferenceStack.push(reference);
    }
    return written;
}
Also used : SelectionKey(java.nio.channels.SelectionKey) SocketTimeoutException(java.net.SocketTimeoutException) NioSocketWrapper(org.apache.tomcat.util.net.NioEndpoint.NioSocketWrapper) EOFException(java.io.EOFException) IOException(java.io.IOException)

Example 2 with NioSocketWrapper

use of org.apache.tomcat.util.net.NioEndpoint.NioSocketWrapper in project tomcat by apache.

the class NioBlockingSelector method read.

/**
     * Performs a blocking read using the bytebuffer for data to be read
     * If the <code>selector</code> parameter is null, then it will perform a busy read that could
     * take up a lot of CPU cycles.
     * @param buf ByteBuffer - the buffer containing the data, we will read as until we have read at least one byte or we timed out
     * @param socket SocketChannel - the socket to write data to
     * @param readTimeout long - the timeout for this read operation in milliseconds, -1 means no timeout
     * @return int - returns the number of bytes read
     * @throws EOFException if read returns -1
     * @throws SocketTimeoutException if the read times out
     * @throws IOException if an IO Exception occurs in the underlying socket logic
     */
public int read(ByteBuffer buf, NioChannel socket, long readTimeout) throws IOException {
    SelectionKey key = socket.getIOChannel().keyFor(socket.getPoller().getSelector());
    if (key == null)
        throw new IOException("Key no longer registered");
    KeyReference reference = keyReferenceStack.pop();
    if (reference == null) {
        reference = new KeyReference();
    }
    NioSocketWrapper att = (NioSocketWrapper) key.attachment();
    int read = 0;
    boolean timedout = false;
    //assume we can read
    int keycount = 1;
    //start the timeout timer
    long time = System.currentTimeMillis();
    try {
        while (!timedout) {
            if (keycount > 0) {
                //only read if we were registered for a read
                read = socket.read(buf);
                if (read != 0) {
                    break;
                }
            }
            try {
                if (att.getReadLatch() == null || att.getReadLatch().getCount() == 0)
                    att.startReadLatch(1);
                poller.add(att, SelectionKey.OP_READ, reference);
                if (readTimeout < 0) {
                    att.awaitReadLatch(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
                } else {
                    att.awaitReadLatch(readTimeout, TimeUnit.MILLISECONDS);
                }
            } catch (InterruptedException ignore) {
            // Ignore
            }
            if (att.getReadLatch() != null && att.getReadLatch().getCount() > 0) {
                //we got interrupted, but we haven't received notification from the poller.
                keycount = 0;
            } else {
                //latch countdown has happened
                keycount = 1;
                att.resetReadLatch();
            }
            if (readTimeout >= 0 && (keycount == 0))
                timedout = (System.currentTimeMillis() - time) >= readTimeout;
        }
        //while
        if (timedout)
            throw new SocketTimeoutException();
    } finally {
        poller.remove(att, SelectionKey.OP_READ);
        if (timedout && reference.key != null) {
            poller.cancelKey(reference.key);
        }
        reference.key = null;
        keyReferenceStack.push(reference);
    }
    return read;
}
Also used : SelectionKey(java.nio.channels.SelectionKey) SocketTimeoutException(java.net.SocketTimeoutException) NioSocketWrapper(org.apache.tomcat.util.net.NioEndpoint.NioSocketWrapper) IOException(java.io.IOException)

Aggregations

IOException (java.io.IOException)2 SocketTimeoutException (java.net.SocketTimeoutException)2 SelectionKey (java.nio.channels.SelectionKey)2 NioSocketWrapper (org.apache.tomcat.util.net.NioEndpoint.NioSocketWrapper)2 EOFException (java.io.EOFException)1