Return-Path: X-Original-To: apmail-tomcat-dev-archive@www.apache.org Delivered-To: apmail-tomcat-dev-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 5FC587CF0 for ; Sat, 22 Oct 2011 21:31:33 +0000 (UTC) Received: (qmail 4673 invoked by uid 500); 22 Oct 2011 21:31:31 -0000 Delivered-To: apmail-tomcat-dev-archive@tomcat.apache.org Received: (qmail 4610 invoked by uid 500); 22 Oct 2011 21:31:31 -0000 Mailing-List: contact dev-help@tomcat.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: "Tomcat Developers List" Delivered-To: mailing list dev@tomcat.apache.org Received: (qmail 4600 invoked by uid 99); 22 Oct 2011 21:31:31 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 22 Oct 2011 21:31:31 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED,T_FRT_STOCK2 X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 22 Oct 2011 21:31:28 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id D613923889E3 for ; Sat, 22 Oct 2011 21:31:07 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1187812 [5/8] - in /tomcat/trunk/modules/tomcat-lite: ./ java/org/apache/coyote/lite/ java/org/apache/tomcat/lite/http/ java/org/apache/tomcat/lite/io/ java/org/apache/tomcat/lite/io/jsse/ java/org/apache/tomcat/lite/proxy/ java/org/apache... Date: Sat, 22 Oct 2011 21:31:02 -0000 To: dev@tomcat.apache.org From: markt@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20111022213107.D613923889E3@eris.apache.org> Modified: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/IOChannel.java URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/IOChannel.java?rev=1187812&r1=1187811&r2=1187812&view=diff ============================================================================== --- tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/IOChannel.java (original) +++ tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/IOChannel.java Sat Oct 22 21:30:59 2011 @@ -9,42 +9,42 @@ import java.nio.channels.ByteChannel; /** - * Buffered, non-blocking ByteChannel. - * - * write() data will be added to the buffer. Call startSending() to - * flush. - * - * - * + * Buffered, non-blocking ByteChannel. + * + * write() data will be added to the buffer. Call startSending() to + * flush. + * + * + * * - you can use it as a normal non-blocking ByteChannel. * - you can call getRead - * + * * Very different from MINA IoFilters, also much lower level. - * - * + * + * * @author Costin Manolache */ -public abstract class IOChannel implements ByteChannel, IOConnector.DataReceivedCallback, - IOConnector.DataFlushedCallback { - +public abstract class IOChannel implements ByteChannel, IOConnector.DataReceivedCallback, + IOConnector.DataFlushedCallback { + /** * If this channel wraps another channel - for example a socket. * Will be null if this is the 'root' channel - a socket, memory. */ protected IOChannel net; - - /** + + /** * Set with another channel layered on top of the current channel. */ protected IOChannel head; - + protected String id; - + /** * A string that can be parsed to extract the target. * host:port for normal sockets */ - protected CharSequence target; + protected CharSequence target; /** * Connector that created the channel. @@ -55,16 +55,16 @@ public abstract class IOChannel implemen * Callbacks. Will be moved if a new head is inserted. */ protected IOConnector.ConnectedCallback connectedCallback; - - /** + + /** * Will be called if any data is received. * Will also be called on close. Close with lastException set indicates * an error condition. */ protected IOConnector.DataReceivedCallback dataReceivedCallback; - + /** - * Out data is buffered, then sent with startSending. + * Out data is buffered, then sent with startSending. * This callback indicates the data has been sent. Can be used * to implement blocking flush. */ @@ -73,15 +73,15 @@ public abstract class IOChannel implemen // Last activity timestamp. // TODO: update and use it ( placeholder ) public long ts; - + /** - * If an async exception happens. + * If an async exception happens. */ protected Throwable lastException; - + protected IOChannel() { } - + public void setConnectedCallback(IOConnector.ConnectedCallback connectedCallback) { this.connectedCallback = connectedCallback; } @@ -92,7 +92,7 @@ public abstract class IOChannel implemen /** * Callback called when the bottom ( OS ) channel has finished flushing. - * + * * @param dataFlushedCallback */ public void setDataFlushedCallback(IOConnector.DataFlushedCallback dataFlushedCallback) { @@ -102,31 +102,31 @@ public abstract class IOChannel implemen // Input public abstract IOBuffer getIn(); - // Output + // Output public abstract IOBuffer getOut(); - - - /** + + + /** * From downstream ( NET ). Pass it to the next channel. */ public void handleReceived(IOChannel net) throws IOException { sendHandleReceivedCallback(); } - - /** - * Called from lower layer (NET) when the last flush is - * done and all buffers have been sent to OS ( or + + /** + * Called from lower layer (NET) when the last flush is + * done and all buffers have been sent to OS ( or * intended recipient ). - * + * * Will call the callback or next filter, may do additional * processing. - * + * * @throws IOException */ public void handleFlushed(IOChannel net) throws IOException { sendHandleFlushedCallback(); } - + private void sendHandleFlushedCallback() throws IOException { try { if (dataFlushedCallback != null) { @@ -142,15 +142,15 @@ public abstract class IOChannel implemen } else { throw new WrappedException("Error in handleFlushed", t); } - } + } } - - + + /** * Notify next channel or callback that data has been received. * Called after a lower channel gets more data ( in the IOThread * for example ). - * + * * Also called when closed stream is detected. Can be called * to just force upper layers to check for data. */ @@ -174,24 +174,24 @@ public abstract class IOChannel implemen } else { throw new WrappedException(t); } - } + } } - /** - * Return last IO exception. - * - * The channel is async, exceptions can happen at any time. - * The normal callback will be called ( connected, received ), it + /** + * Return last IO exception. + * + * The channel is async, exceptions can happen at any time. + * The normal callback will be called ( connected, received ), it * should check if the channel is closed and the exception. */ public Throwable lastException() { return lastException; } - + public void close() throws IOException { shutdownOutput(); - // Should it read the buffers ? - + // Should it read the buffers ? + if (getIn() == null || getIn().isAppendClosed()) { return; } else { @@ -202,11 +202,11 @@ public abstract class IOChannel implemen } public boolean isOpen() { - return getIn() != null && - getOut() != null && + return getIn() != null && + getOut() != null && !getIn().isAppendClosed() && !getOut().isAppendClosed(); } - + public void shutdownOutput() throws IOException { if (getOut() == null || getOut().isAppendClosed()) { return; @@ -225,18 +225,18 @@ public abstract class IOChannel implemen } // Chaining/filtering - - /** - * Called to add an filter after the current channel, for + + /** + * Called to add an filter after the current channel, for * example set SSL on top of a socket channel. - * + * * The 'next' channel will have the received/flushed callbacks * of the current channel. The current channel's callbacks will * be reset. - * + * * "Head" is from STREAMS. - * - * @throws IOException + * + * @throws IOException */ public IOChannel setHead(IOChannel head) throws IOException { this.head = head; @@ -266,21 +266,21 @@ public abstract class IOChannel implemen } } } - + // Socket support - + public void readInterest(boolean b) throws IOException { if (net != null) { net.readInterest(b); } } - + // Helpers public int read(ByteBuffer bb) throws IOException { return getIn().read(bb); } - + public int readNonBlocking(ByteBuffer bb) throws IOException { return getIn().read(bb); } @@ -288,21 +288,21 @@ public abstract class IOChannel implemen public void waitFlush(long timeMs) throws IOException { return; } - + public int readBlocking(ByteBuffer bb, long timeMs) throws IOException { getIn().waitData(timeMs); return getIn().read(bb); } - - /** - * Capture all output in a buffer. + + /** + * Capture all output in a buffer. */ - public BBuffer readAll(BBuffer chunk, long to) + public BBuffer readAll(BBuffer chunk, long to) throws IOException { if (chunk == null) { chunk = BBuffer.allocate(); } - while (true) { + while (true) { getIn().waitData(to); BBucket next = getIn().peekFirst(); if (getIn().isClosedAndEmpty() && next == null) { @@ -315,11 +315,11 @@ public abstract class IOChannel implemen getIn().advance(next.remaining()); } } - + public int write(ByteBuffer bb) throws IOException { return getOut().write(bb); } - + public void write(byte[] data) throws IOException { getOut().append(data, 0, data.length); } @@ -327,29 +327,29 @@ public abstract class IOChannel implemen public void write(String string) throws IOException { write(string.getBytes()); } - - /** + + /** * Send data in out to the intended recipient. * This is not blocking. */ public abstract void startSending() throws IOException; - + public void setId(String id) { this.id = id; } - + public String getId() { return id; } - + public CharSequence getTarget() { if (net != null) { return net.getTarget(); } return target; } - + public void setTarget(CharSequence target) { this.target = target; } @@ -360,12 +360,12 @@ public abstract class IOChannel implemen public static final String ATT_LOCAL_PORT = "LocalPort"; public static final String ATT_LOCAL_ADDRESS = "LocalAddress"; public static final String ATT_REMOTE_ADDRESS = "RemoteAddress"; - + public Object getAttribute(String name) { if (net != null) { return net.getAttribute(name); } - return null; + return null; } - + } Modified: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/IOConnector.java URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/IOConnector.java?rev=1187812&r1=1187811&r2=1187812&view=diff ============================================================================== --- tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/IOConnector.java (original) +++ tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/IOConnector.java Sat Oct 22 21:30:59 2011 @@ -8,23 +8,23 @@ import java.util.Timer; /** * Factory for IOChannels, with support for caching. - * - * + * + * * @author Costin Manolache */ public abstract class IOConnector { public static interface DataReceivedCallback { - /** + /** * Called when data or EOF has been received. */ public void handleReceived(IOChannel ch) throws IOException; } - /** + /** * Callback for accept and connect. * - * Will also be called if an error happens while connecting, in + * Will also be called if an error happens while connecting, in * which case the connection will be closed. */ public static interface ConnectedCallback { @@ -36,28 +36,28 @@ public abstract class IOConnector { } protected Timer timer; - + public Timer getTimer() { return timer; } - + /** * If the connector is layered on top of a different connector, - * return the lower layer ( for example the socket connector) + * return the lower layer ( for example the socket connector) */ public IOConnector getNet() { return null; } - - public abstract void acceptor(IOConnector.ConnectedCallback sc, + + public abstract void acceptor(IOConnector.ConnectedCallback sc, CharSequence port, Object extra) - throws IOException; - - // TODO: failures ? + throws IOException; + + // TODO: failures ? // TODO: use String target or url - public abstract void connect(String host, int port, + public abstract void connect(String host, int port, IOConnector.ConnectedCallback sc) throws IOException; - + public void stop() { if (timer != null) { timer.cancel(); Modified: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/IOInputStream.java URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/IOInputStream.java?rev=1187812&r1=1187811&r2=1187812&view=diff ============================================================================== --- tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/IOInputStream.java (original) +++ tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/IOInputStream.java Sat Oct 22 21:30:59 2011 @@ -9,21 +9,21 @@ import java.io.InputStream; /** * Similar with ServletInputStream - adds readLine(byte[]..), using * a IOBuffer. - * - * - * + * + * + * * @author Costin Manolache */ public class IOInputStream extends InputStream { IOBuffer bb; long timeout; - + public IOInputStream(IOChannel httpCh, long to) { bb = httpCh.getIn(); this.timeout = to; } - + @Override public int read() throws IOException { // getReadableBucket/peekFirst returns a buffer with at least @@ -35,10 +35,10 @@ public class IOInputStream extends Input if (bb.isClosedAndEmpty()) { return -1; } - + return bb.read(); } - + public int read(byte[] buf, int off, int len) throws IOException { if (bb.isClosedAndEmpty()) { return -1; Modified: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/IOOutputStream.java URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/IOOutputStream.java?rev=1187812&r1=1187811&r2=1187812&view=diff ============================================================================== --- tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/IOOutputStream.java (original) +++ tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/IOOutputStream.java Sat Oct 22 21:30:59 2011 @@ -10,21 +10,21 @@ import java.text.MessageFormat; /** * Same methods with ServletOutputStream. - * - * There is no restriction in using the Writer and InputStream at the - * same time - the servlet layer will impose it for compat. You can also use - * IOBuffer directly. - * + * + * There is no restriction in using the Writer and InputStream at the + * same time - the servlet layer will impose it for compat. You can also use + * IOBuffer directly. + * * If you mix stream and writer: * - call BufferWriter.push() to make sure all chars are sent down - * - the BufferOutputStream doesn't cache any data, all goes to the + * - the BufferOutputStream doesn't cache any data, all goes to the * IOBuffer. * - flush() on BufferOutputStream and BufferWriter will send the data * to the network and block until it gets to the socket ( so it can - * throw exception ). + * throw exception ). * - You can also use non-blocking flush methods in IOBuffer, and a * callback if you want to know when the write was completed. - * + * * @author Costin Manolache */ public class IOOutputStream extends OutputStream { @@ -32,9 +32,9 @@ public class IOOutputStream extends Outp IOBuffer bb; IOChannel ch; int bufferSize = 8 * 1024; - + int wSinceFlush = 0; - + public IOOutputStream(IOBuffer out, IOChannel httpMessage) { this.bb = out; ch = httpMessage; @@ -44,7 +44,7 @@ public class IOOutputStream extends Outp wSinceFlush = 0; bufferSize = 8 * 1024; } - + public void reset() { wSinceFlush = 0; bb.clear(); @@ -71,28 +71,28 @@ public class IOOutputStream extends Outp flush(); } } - + @Override public void write(int b) throws IOException { bb.append((char) b); updateSize(1); } - + @Override public void write(byte data[]) throws IOException { write(data, 0, data.length); - } + } @Override public void write(byte data[], int start, int len) throws IOException { bb.append(data, start, len); updateSize(len); - } - + } + public void flush() throws IOException { if (ch != null) { ch.startSending(); - + ch.waitFlush(Long.MAX_VALUE); } wSinceFlush = 0; @@ -102,13 +102,13 @@ public class IOOutputStream extends Outp flush(); bb.close(); } - + public void write(ByteBuffer source) throws IOException { write(source.array(), source.position(), source.remaining()); source.position(source.limit()); } - + public void print(String s) throws IOException { if (s==null) s="null"; int len = s.length(); Modified: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/IOReader.java URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/IOReader.java?rev=1187812&r1=1187811&r2=1187812&view=diff ============================================================================== --- tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/IOReader.java (original) +++ tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/IOReader.java Sat Oct 22 21:30:59 2011 @@ -19,32 +19,32 @@ import java.util.concurrent.atomic.Atomi /** * Conversion from Bytes to Chars and support for decoding. - * - * Replaces tomcat B2CConverter with NIO equivalent. B2CConverter was a hack - * (re)using an dummy InputStream backed by a ByteChunk. - * + * + * Replaces tomcat B2CConverter with NIO equivalent. B2CConverter was a hack + * (re)using an dummy InputStream backed by a ByteChunk. + * * @author Costin Manolache */ public class IOReader extends Reader { - + IOBuffer iob; Map decoders = new HashMap(); CharsetDecoder decoder; - + private static boolean REUSE = true; String enc; private boolean closed; public static final String DEFAULT_ENCODING = "ISO-8859-1"; long timeout = 0; - + public IOReader(IOBuffer iob) { this.iob = iob; } - + public void setTimeout(long to) { timeout = to; } - + public void setEncoding(String charset) { enc = charset; if (enc == null) { @@ -60,11 +60,11 @@ public class IOReader extends Reader { } } } - + public String getEncoding() { return enc; } - + public void recycle() { if (decoder != null) { decoder.reset(); @@ -72,11 +72,11 @@ public class IOReader extends Reader { closed = false; enc = null; } - + private void checkClosed() throws IOException { if (closed) throw new IOException("closed"); } - + public boolean ready() { return iob.peekFirst() != null; } @@ -97,14 +97,14 @@ public class IOReader extends Reader { else return cb[0]; } - + @Override public void close() throws IOException { closed = true; iob.close(); } - - /** + + /** * Used if a bucket ends on a char boundary */ BBuffer underFlowBuffer = BBuffer.allocate(10); @@ -114,7 +114,7 @@ public class IOReader extends Reader { * Decode all bytes - for example a URL or header. */ public void decodeAll(BBucket bb, CBuffer c) { - + while (bb.hasRemaining()) { CharBuffer charBuffer = c.getAppendCharBuffer(); CoderResult res = decode1(bb, charBuffer, true); @@ -122,15 +122,15 @@ public class IOReader extends Reader { if (res != CoderResult.OVERFLOW) { if (res == CoderResult.UNDERFLOW || bb.hasRemaining()) { System.err.println("Ignored trailing bytes " + bb.remaining()); - } + } return; } } - + } - - /** - * Do one decode pass. + + /** + * Do one decode pass. */ public CoderResult decode1(BBucket bb, CharBuffer c, boolean eof) { ByteBuffer b = bb.getByteBuffer(); @@ -155,33 +155,33 @@ public class IOReader extends Reader { "10 bytes"); } } - + CoderResult res = decoder.decode(b, c, eof); bb.position(b.position()); - + if (res == CoderResult.UNDERFLOW && bb.hasRemaining()) { // b ends on a boundary underFlowBuffer.append(bb.array(), bb.position(), bb.remaining()); bb.position(bb.limit()); - } + } return res; } - + @Override public int read(char[] cbuf, int offset, int length) throws IOException { checkClosed(); if (length == 0) { return 0; } - // we can either allocate a new CharBuffer or use a + // we can either allocate a new CharBuffer or use a // static one and copy. Seems simpler this way - needs some // load test, but InputStreamReader seems to do the same. CharBuffer out = CharBuffer.wrap(cbuf, offset, length); - + CoderResult result = CoderResult.UNDERFLOW; BBucket bucket = iob.peekFirst(); - + // Consume as much as possible without blocking while (result == CoderResult.UNDERFLOW) { // fill the buffer if needed @@ -199,7 +199,7 @@ public class IOReader extends Reader { break; } } - + if (bucket == null) { // eof break; @@ -211,7 +211,7 @@ public class IOReader extends Reader { if (result == CoderResult.UNDERFLOW && iob.isClosedAndEmpty()) { // Flush out any remaining data - ByteBuffer bytes = bucket == null ? + ByteBuffer bytes = bucket == null ? underFlowBuffer.getByteBuffer() : bucket.getByteBuffer(); result = decoder.decode(bytes, out, true); if (bucket == null) { Modified: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/IOWriter.java URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/IOWriter.java?rev=1187812&r1=1187811&r2=1187812&view=diff ============================================================================== --- tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/IOWriter.java (original) +++ tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/IOWriter.java Sat Oct 22 21:30:59 2011 @@ -15,32 +15,32 @@ import java.util.Map; /** * Converts chars to bytes, and associated encoding. - * - * Replaces C2B from old tomcat. - * + * + * Replaces C2B from old tomcat. + * * @author Costin Manolache */ public class IOWriter extends Writer { - + IOBuffer iob; Map encoders = new HashMap(); CharsetEncoder encoder; - + private static boolean REUSE = true; String enc; private boolean closed; IOChannel ioCh; - + public IOWriter(IOChannel iob) { this.ioCh = iob; if (iob != null) { this.iob = iob.getOut(); } } - + public void setEncoding(String charset) { if (charset == null) { - charset = "UTF-8"; + charset = "UTF-8"; } enc = charset; encoder = getEncoder(charset); @@ -53,10 +53,10 @@ public class IOWriter extends Writer { } } } - + CharsetEncoder getEncoder(String charset) { if (charset == null) { - charset = "UTF-8"; + charset = "UTF-8"; } encoder = REUSE ? encoders.get(charset) : null; if (encoder == null) { @@ -69,11 +69,11 @@ public class IOWriter extends Writer { } return encoder; } - + public String getEncoding() { return enc; } - + public void recycle() { if (encoder != null) { encoder.reset(); @@ -81,12 +81,12 @@ public class IOWriter extends Writer { closed = false; enc = null; } - - + + private void checkClosed() throws IOException { if (closed) throw new IOException("closed"); } - + @Override public void close() throws IOException { closed = true; @@ -94,16 +94,16 @@ public class IOWriter extends Writer { ByteBuffer out = iob.getWriteBuffer(); encoder.flush(out); iob.releaseWriteBuffer(1); - + iob.close(); } - - /** + + /** * Used if a bucket ends on a char boundary */ CBuffer underFlowBuffer = CBuffer.newInstance(); - public void encode1(CBuffer cc, + public void encode1(CBuffer cc, BBuffer bb, CharsetEncoder encoder, boolean eof) { CharBuffer c = cc.getNioBuffer(); ByteBuffer b = bb.getWriteByteBuffer(c.remaining() * 2); @@ -112,41 +112,41 @@ public class IOWriter extends Writer { bb.limit(b.position()); } - /** - * + /** + * * @param cc * @return */ - public void encode1(CharBuffer c, + public void encode1(CharBuffer c, ByteBuffer b, CharsetEncoder encoder, boolean eof) { - + // TODO: buffer growth in caller - + CoderResult res = encoder.encode(c, b, eof); if (res == CoderResult.OVERFLOW) { - // bb is full - next call will get a larger buffer ( it + // bb is full - next call will get a larger buffer ( it // grows ) or maybe will be flushed. } if (res == CoderResult.UNDERFLOW && c.remaining() > 0 && !eof) { // TODO: if eof -> exception ? // cc has remaining chars - for example a surrogate start. underFlowBuffer.put(c); - } - + } + } - public void encodeAll(CBuffer cc, + public void encodeAll(CBuffer cc, BBuffer bb, CharsetEncoder encoder, boolean eof) { while (cc.length() > 0) { encode1(cc, bb, encoder, eof); } - } + } - public void encodeAll(CBuffer cc, + public void encodeAll(CBuffer cc, BBuffer bb, String cs) { encodeAll(cc, bb, getEncoder(cs), true); - } - + } + @Override public void flush() throws IOException { if (ioCh != null) { @@ -182,31 +182,31 @@ public class IOWriter extends Writer { return 4; } - + return i; } /** * Just send the chars to the byte[], without flushing down. - * + * * @throws IOException */ public void push() throws IOException { // we don't cache here. } - + @Override public void write(char[] cbuf, int off, int len) throws IOException { checkClosed(); CharBuffer cb = CharBuffer.wrap(cbuf, off, len); - + while (cb.remaining() > 0) { ByteBuffer wb = iob.getWriteBuffer(); encode1(cb, wb, encoder, false); iob.releaseWriteBuffer(1); } } - - + + } Modified: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/MemoryIOConnector.java URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/MemoryIOConnector.java?rev=1187812&r1=1187811&r2=1187812&view=diff ============================================================================== --- tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/MemoryIOConnector.java (original) +++ tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/MemoryIOConnector.java Sat Oct 22 21:30:59 2011 @@ -15,15 +15,15 @@ public class MemoryIOConnector extends I } }; IOBuffer netOut = new IOBuffer(this); - + /** * All flushed output will be saved to 'out'. */ public BBuffer out = BBuffer.allocate(4096); - + public MemoryIOChannel() { } - + public void startSending() throws IOException { // IOBuffer bb = netOut; @@ -43,7 +43,7 @@ public class MemoryIOConnector extends I handleFlushed(this); } - + @Override public IOBuffer getIn() { return netIn; @@ -52,23 +52,23 @@ public class MemoryIOConnector extends I public IOBuffer getOut() { return netOut; } - } - + } + // TODO: in-process communication without sockets for testing ConnectedCallback acceptor; MemoryIOConnector server; - + public MemoryIOConnector() { timer = new Timer(true); } - + public MemoryIOConnector withServer(MemoryIOConnector server) { this.server = server; return server; } - + @Override - public void acceptor(ConnectedCallback sc, CharSequence port, Object extra) + public void acceptor(ConnectedCallback sc, CharSequence port, Object extra) throws IOException { this.acceptor = sc; } @@ -84,5 +84,5 @@ public class MemoryIOConnector extends I } sc.handleConnected(ch); } - + } \ No newline at end of file Modified: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/NioChannel.java URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/NioChannel.java?rev=1187812&r1=1187811&r2=1187812&view=diff ============================================================================== --- tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/NioChannel.java (original) +++ tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/NioChannel.java Sat Oct 22 21:30:59 2011 @@ -7,45 +7,45 @@ import java.nio.channels.ByteChannel; import java.nio.channels.Channel; -/** +/** * Wrapper around the real channel, with selector-specific info. - * + * * It is stored as an attachment in the selector. */ public class NioChannel implements ByteChannel { - + public static interface NioChannelCallback { public void handleConnected(NioChannel ch) throws IOException; public void handleClosed(NioChannel ch) throws IOException; public void handleReadable(NioChannel ch) throws IOException; public void handleWriteable(NioChannel ch) throws IOException; - + } - + NioChannel(NioThread sel) { this.sel = sel; } // APR long is wrapped in a ByteChannel as well - with few other longs. Channel channel; - + // sync access. Object selKey; NioThread sel; - - /** + + /** * If != 0 - the callback will be notified closely after this time. - * Used for timeouts. + * Used for timeouts. */ long nextTimeEvent = 0; - + // Callbacks Runnable timeEvent; - + NioChannelCallback callback; - + Throwable lastException; // True if the callback wants to be notified of read/write @@ -54,23 +54,23 @@ public class NioChannel implements ByteC // shutdownOutput has been called ? private boolean outClosed = false; - + // read() returned -1 OR input buffer closed ( no longer interested ) boolean inClosed = false; - + // Saved to allow debug messages for bad interest/looping int lastReadResult; int zeroReads = 0; int lastWriteResult; - + protected NioChannel() { - + } - + public NioThread getSelectorThread() { return sel; } - + public String toString() { StringBuffer sb = new StringBuffer(); sb.append("SelData/") @@ -80,19 +80,19 @@ public class NioChannel implements ByteC .append(inClosed ? "In-CLOSE/" : "") .append("/") .append(channel.toString()); - + return sb.toString(); } - + public Channel getChannel() { return channel; } - + public boolean isOpen() { // in and out open return channel.isOpen() && !outClosed && !inClosed; } - + public int read(ByteBuffer bb) throws IOException { return sel.readNonBlocking(this, bb); } @@ -100,7 +100,7 @@ public class NioChannel implements ByteC public int write(ByteBuffer bb) throws IOException { return sel.writeNonBlocking(this, bb); } - + public void readInterest(boolean b) throws IOException { sel.readInterest(this, b); } @@ -108,7 +108,7 @@ public class NioChannel implements ByteC public void writeInterest() throws IOException { sel.writeInterest(this); } - + public InetAddress getAddress(boolean remote) { return sel.getAddress(this, remote); } @@ -116,7 +116,7 @@ public class NioChannel implements ByteC public int getPort(boolean remote) { return sel.getPort(this, remote); } - + /** * Run in selector thread. */ @@ -125,28 +125,28 @@ public class NioChannel implements ByteC } /** - * Request a timer event. The thread will generate the events at + * Request a timer event. The thread will generate the events at * a configurable interval - for example no more often than 0.5 sec. */ public void setTimer(long timeMs, Runnable cb) { this.nextTimeEvent = timeMs; this.timeEvent = cb; } - + /** * shutdown out + in * If there is still data in the input buffer - RST will be sent * instead of FIN. - * - * - * The proper way to close a connection is to shutdownOutput() first, + * + * + * The proper way to close a connection is to shutdownOutput() first, * wait until read() return -1, then call close(). - * + * * If read() returns -1, you need to finish sending, call shutdownOutput() - * than close. - * If read() returns -1 and there is an error - call close() - * directly. - * + * than close. + * If read() returns -1 and there is an error - call close() + * directly. + * */ @Override public void close() throws IOException { @@ -157,9 +157,9 @@ public class NioChannel implements ByteC /** * Send TCP close(FIN). HTTP uses this to transmit end of body. The other end * detects this with a '-1' in read(). - * + * * All other forms of close() are reported as exceptions in read(). - * + * * @throws IOException */ public void shutdownOutput() throws IOException { @@ -171,13 +171,13 @@ public class NioChannel implements ByteC } catch (IOException ex) { // ignore } - } + } if (inClosed) { sel.close(this, null); } } } - + void inputClosed() throws IOException { synchronized (channel) { if (inClosed) { @@ -193,6 +193,6 @@ public class NioChannel implements ByteC } } } - + boolean closeCalled = false; } \ No newline at end of file Modified: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/NioThread.java URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/NioThread.java?rev=1187812&r1=1187811&r2=1187812&view=diff ============================================================================== --- tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/NioThread.java (original) +++ tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/NioThread.java Sat Oct 22 21:30:59 2011 @@ -46,13 +46,13 @@ import org.apache.tomcat.lite.io.NioChan /** * Abstract NIO/APR to avoid some of the complexity and allow more code - * sharing and experiments. + * sharing and experiments. * - * SelectorThread provides non-blocking methods for read/write and generates - * callbacks using SelectorCallback. It has no buffers of its own. + * SelectorThread provides non-blocking methods for read/write and generates + * callbacks using SelectorCallback. It has no buffers of its own. + * + * This is non-blocking, non-buffering and uses callbacks. * - * This is non-blocking, non-buffering and uses callbacks. - * * @author Costin Manolache */ public class NioThread implements Runnable { @@ -78,12 +78,12 @@ public class NioThread implements Runnab AtomicInteger opened = new AtomicInteger(); AtomicInteger closed = new AtomicInteger(); AtomicInteger loops = new AtomicInteger(); - + AtomicInteger callbackCount = new AtomicInteger(); AtomicLong callbackTotalTime = new AtomicLong(); long maxCallbackTime = 0; - // actives are also stored in the Selector. This is only updated in the main + // actives are also stored in the Selector. This is only updated in the main // thread public ArrayList active = new ArrayList(); @@ -94,45 +94,45 @@ public class NioThread implements Runnab long lastWakeup = System.currentTimeMillis(); // last time we woke long nextWakeup; // next scheduled wakeup - // Normally select will wait for the next time event - if it's + // Normally select will wait for the next time event - if it's // too far in future, maxSleep will override it. private long maxSleep = 600000; long sleepTime = maxSleep; - // Never sleep less than minSleep. This defines the resulution for + // Never sleep less than minSleep. This defines the resulution for // time events. private long minSleep = 100; boolean daemon = false; - + // TODO: trace log - record all events with timestamps, replay public NioThread(String name, boolean daemon) { try { selectorThread = (name == null) ? new Thread(this) : new Thread(this, name); - + selector = Selector.open(); // TODO: start it on-demand, close it when not in use selectorThread.setDaemon(daemon); this.daemon = daemon; - + selectorThread.start(); - + } catch(IOException e) { throw new RuntimeException(e); - } + } } - + /** - * Opened sockets, waiting for something ( close at least ) + * Opened sockets, waiting for something ( close at least ) */ public int getOpen() { return opened.get(); } /** - * Closed - we're done with them. + * Closed - we're done with them. */ public int getClosed() { return closed.get(); @@ -141,11 +141,11 @@ public class NioThread implements Runnab public int getActive() { return active.size(); } - + public int getCallbacks() { return callbackCount.get(); } - + public long getMaxCallbackTime() { return maxCallbackTime; } @@ -157,8 +157,8 @@ public class NioThread implements Runnab } return callbackTotalTime.get() / cnt; } - - /** + + /** * How many times we looped */ public int getLoops() { @@ -173,7 +173,7 @@ public class NioThread implements Runnab return System.currentTimeMillis() - lastWakeup; } - /** + /** * Close all resources, stop accepting, stop the thread. * The actual stop will happen in background. */ @@ -194,7 +194,7 @@ public class NioThread implements Runnab // if we want timeouts - set here. try { loops.incrementAndGet(); - + // Check if new requests were added processPending(); @@ -204,9 +204,9 @@ public class NioThread implements Runnab // We don't want to iterate on every I/O updateSleepTimeAndProcessTimeouts(now); } - + int selected = selector.select(sleepTime); - + lastWakeup = System.currentTimeMillis(); long slept = lastWakeup - now; @@ -224,7 +224,7 @@ public class NioThread implements Runnab } sloops++; } - + // handle events for existing req first. if (selected != 0) { sloops = 0; @@ -237,14 +237,14 @@ public class NioThread implements Runnab long beforeCallback = System.currentTimeMillis(); SelectionKey sk = i.next(); i.remove(); - + boolean valid = sk.isValid(); int readyOps = (valid) ? sk.readyOps() : 0; - + NioChannel ch = (NioChannel) sk.attachment(); if (debugWakeup) { - log.info("Wakeup selCnt=" + selected + " slept=" + (lastWakeup - now) + - " ready: " + readyOps + " v=" + + log.info("Wakeup selCnt=" + selected + " slept=" + (lastWakeup - now) + + " ready: " + readyOps + " v=" + sk.isValid() + " ch=" + ch); } if (ch == null) { @@ -295,13 +295,13 @@ public class NioThread implements Runnab // Leave readable interest ! handleReadable(ch); } - - long callbackTime = + + long callbackTime = System.currentTimeMillis() - beforeCallback; - - if (callbackTime > 250) { - log.warning("Callback too long ! ops=" + ready + - " time=" + callbackTime + " ch=" + ch + + + if (callbackTime > 250) { + log.warning("Callback too long ! ops=" + ready + + " time=" + callbackTime + " ch=" + ch + " " + callbackCnt); } if (callbackTime > maxCallbackTime) { @@ -309,7 +309,7 @@ public class NioThread implements Runnab } callbackCount.incrementAndGet(); this.callbackTotalTime.addAndGet(callbackTime); - + } catch (Throwable t) { log.log(Level.SEVERE, "SelectorThread: Channel error, closing", t); ch.lastException = t; @@ -329,9 +329,9 @@ public class NioThread implements Runnab } private void log(String msg, int selected, long slept, SelectionKey sk, int readyOps) { - log.info(msg + " " + selected - + " " + slept - + " ready: " + readyOps + " " + log.info(msg + " " + selected + + " " + slept + + " ready: " + readyOps + " " + sk.readyOps() + " " + sk); } @@ -347,7 +347,7 @@ public class NioThread implements Runnab oldCh.add(cd); k.cancel(); } - + selector.close(); selector = Selector.open(); for (int i = 0; i < oldCh.size(); i++) { @@ -357,17 +357,17 @@ public class NioThread implements Runnab } int interest = interests.get(i); if (selectorData.channel instanceof ServerSocketChannel) { - ServerSocketChannel socketChannel = + ServerSocketChannel socketChannel = (ServerSocketChannel) selectorData.channel; selectorData.selKey = socketChannel.register(selector, SelectionKey.OP_ACCEPT); } else { SocketChannel socketChannel = (SocketChannel) selectorData.channel; if (interest != 0) { - selectorData.selKey = socketChannel.register(selector, + selectorData.selKey = socketChannel.register(selector, interest); } - + } } } @@ -381,9 +381,9 @@ public class NioThread implements Runnab log.warning("LOOP: read interest" + " after incomplete read"); ch.close(); - } + } } - + private void handleDataWriteable(NioChannel ch) throws IOException { ch.lastWriteResult = 0; if (ch.callback != null) { @@ -404,7 +404,7 @@ public class NioThread implements Runnab ch.sel = this; //sc.socket().setSoLinger(true, 0); if (debug) { - log.info("connected() " + ch + " isConnected()=" + sc.isConnected() + " " + + log.info("connected() " + ch + " isConnected()=" + sc.isConnected() + " " + sc.isConnectionPending()); } @@ -428,13 +428,13 @@ public class NioThread implements Runnab ServerSocketChannel ssc=(ServerSocketChannel)selc; SocketChannel sockC = ssc.accept(); sockC.configureBlocking(false); - + NioChannel acceptedChannel = new NioChannel(this); - acceptedChannel.selKey = sockC.register(selector, - SelectionKey.OP_READ, + acceptedChannel.selKey = sockC.register(selector, + SelectionKey.OP_READ, acceptedChannel); acceptedChannel.channel = sockC; - + synchronized (active) { active.add(acceptedChannel); } @@ -447,10 +447,10 @@ public class NioThread implements Runnab } catch (Throwable t) { log.log(Level.SEVERE, "SelectorThread: Channel error, closing ", t); acceptedChannel.lastException = t; - acceptedChannel.close(); + acceptedChannel.close(); } } - + //sk.interestOps(sk.interestOps() | SelectionKey.OP_ACCEPT); if (debug) { log.info("handleAccept " + ch); @@ -470,9 +470,9 @@ public class NioThread implements Runnab } } } - - /** - * Called from the IO thread + + /** + * Called from the IO thread */ private void closeIOThread(NioChannel ch, boolean remove) { SelectionKey sk = (SelectionKey) ch.selKey; @@ -497,7 +497,7 @@ public class NioThread implements Runnab sk.cancel(); ch.selKey = null; } - + if (channel instanceof SocketChannel) { SocketChannel sc = (SocketChannel) channel; @@ -519,7 +519,7 @@ public class NioThread implements Runnab channel.close(); closed.incrementAndGet(); - + if (ch.callback != null) { ch.callback.handleClosed(ch); } @@ -537,17 +537,17 @@ public class NioThread implements Runnab // --------------- Socket op abstractions ------------ - public int readNonBlocking(NioChannel selectorData, ByteBuffer bb) + public int readNonBlocking(NioChannel selectorData, ByteBuffer bb) throws IOException { try { int off = bb.position(); int done = 0; - + done = ((SocketChannel) selectorData.channel).read(bb); - + if (debug) { - log.info("-------------readNB rd=" + done + " bb.limit=" + + log.info("-------------readNB rd=" + done + " bb.limit=" + bb.limit() + " pos=" + bb.position() + " " + selectorData); } if (done > 0) { @@ -581,7 +581,7 @@ public class NioThread implements Runnab return done; } catch(IOException ex) { if (debug) { - log.info("readNB error rd=" + -1 + " bblen=" + + log.info("readNB error rd=" + -1 + " bblen=" + (bb.limit() - bb.position()) + " " + selectorData + " " + ex); } // common case: other side closed the connection. No need for trace @@ -597,21 +597,21 @@ public class NioThread implements Runnab /** * May be called from any thread */ - public int writeNonBlocking(NioChannel selectorData, ByteBuffer bb) + public int writeNonBlocking(NioChannel selectorData, ByteBuffer bb) throws IOException { try { if (debug) { - log.info("writeNB pos=" + bb.position() + " len=" + + log.info("writeNB pos=" + bb.position() + " len=" + (bb.limit() - bb.position()) + " " + selectorData); if (!bb.isDirect()) { String s = new String(bb.array(), bb.position(), - + bb.limit() - bb.position()); log.info("Data:\n" + s); } } if (selectorData.writeInterest) { - // writeInterest will be false after a callback, if it is + // writeInterest will be false after a callback, if it is // set it means we want to wait for the callback. if (debug) { log.info("Prevent writeNB when writeInterest is set"); @@ -625,8 +625,8 @@ public class NioThread implements Runnab return done; } catch(IOException ex) { if (debug) { - log.info("writeNB error pos=" + bb.position() + " len=" + - (bb.limit() - bb.position()) + " " + selectorData + " " + + log.info("writeNB error pos=" + bb.position() + " len=" + + (bb.limit() - bb.position()) + " " + selectorData + " " + ex); } //ex.printStackTrace(); @@ -638,18 +638,18 @@ public class NioThread implements Runnab } public int getPort(NioChannel sd, boolean remote) { - SocketChannel socketChannel = (SocketChannel) sd.channel; - + SocketChannel socketChannel = (SocketChannel) sd.channel; + if (remote) { return socketChannel.socket().getPort(); } else { return socketChannel.socket().getLocalPort(); } } - + public InetAddress getAddress(NioChannel sd, boolean remote) { - SocketChannel socketChannel = (SocketChannel) sd.channel; - + SocketChannel socketChannel = (SocketChannel) sd.channel; + if (remote) { return socketChannel.socket().getInetAddress(); } else { @@ -657,21 +657,21 @@ public class NioThread implements Runnab } } - /** + /** */ - public void connect(String host, int port, NioChannelCallback cstate) + public void connect(String host, int port, NioChannelCallback cstate) throws IOException { connect(new InetSocketAddress(host, port), cstate); } - + public void connect(SocketAddress sa, NioChannelCallback cstate) throws IOException { connect(sa, cstate, null); } - - public void connect(SocketAddress sa, NioChannelCallback cstate, - NioChannel filter) + + public void connect(SocketAddress sa, NioChannelCallback cstate, + NioChannel filter) throws IOException { SocketChannel socketChannel = SocketChannel.open(); @@ -681,10 +681,10 @@ public class NioThread implements Runnab selectorData.callback = cstate; selectorData.channel = socketChannel; selectorData.channel = socketChannel; // no key - + socketChannel.connect(sa); opened.incrementAndGet(); - + synchronized (connectAcceptInterest) { connectAcceptInterest.add(selectorData); } @@ -700,16 +700,16 @@ public class NioThread implements Runnab // TODO public void setSocketOptions(NioChannel selectorData, - int linger, + int linger, boolean tcpNoDelay, int socketTimeout) throws IOException { - SocketChannel socketChannel = + SocketChannel socketChannel = (SocketChannel) selectorData.channel; Socket socket = socketChannel.socket(); - if(linger >= 0 ) + if(linger >= 0 ) socket.setSoLinger( true, linger); if( tcpNoDelay ) socket.setTcpNoDelay(tcpNoDelay); @@ -717,7 +717,7 @@ public class NioThread implements Runnab socket.setSoTimeout( socketTimeout ); } - /** + /** * Can be called from multiple threads or multiple times. */ public int close(NioChannel selectorData, Throwable exception) throws IOException { @@ -739,18 +739,18 @@ public class NioThread implements Runnab } - public void acceptor(NioChannelCallback cstate, - int port, - InetAddress inet, + public void acceptor(NioChannelCallback cstate, + int port, + InetAddress inet, int backlog, int serverTimeout) - throws IOException + throws IOException { ServerSocketChannel ssc=ServerSocketChannel.open(); ServerSocket serverSocket = ssc.socket(); - + SocketAddress sa = null; - + if (inet == null) { sa = new InetSocketAddress( port ); } else { @@ -764,23 +764,23 @@ public class NioThread implements Runnab if( serverTimeout >= 0 ) { serverSocket.setSoTimeout( serverTimeout ); } - + ssc.configureBlocking(false); NioChannel selectorData = new NioChannel(this); selectorData.channel = ssc; // no key yet - selectorData.callback = cstate; + selectorData.callback = cstate; // key will be set in pending // TODO: add SSL here - + synchronized (connectAcceptInterest) { connectAcceptInterest.add(selectorData); } selector.wakeup(); } - + public void runInSelectorThread(Runnable cb) throws IOException { if (isSelectorThread()) { cb.run(); @@ -793,25 +793,25 @@ public class NioThread implements Runnab } /** - * Example config: - * + * Example config: + * * www stream tcp wait USER PATH_TO_tomcatInetd.sh - * + * * For a different port, you need to add it to /etc/services. - * - * 'wait' is critical - the common use of inetd is 'nowait' for + * + * 'wait' is critical - the common use of inetd is 'nowait' for * tcp services, which doesn't make sense for java ( too slow startup * time ). It may make sense in future with something like android VM. - * + * * In 'wait' mode, inetd will pass the acceptor socket to java - so * you can listen on port 80 and run as regular user with no special * code and magic. * If tomcat dies, inetd will get back the acceptor and on next connection - * restart tomcat. - * + * restart tomcat. + * * This also works with xinetd. It might work with Apple launchd. - * - * TODO: detect inactivity for N minutes, exist - to free resources. + * + * TODO: detect inactivity for N minutes, exist - to free resources. */ public void inetdAcceptor(NioChannelCallback cstate) throws IOException { SelectorProvider sp=SelectorProvider.provider(); @@ -826,7 +826,7 @@ public class NioThread implements Runnab NioChannel selectorData = new NioChannel(this); selectorData.channel = ssc; selectorData.callback = cstate; - + synchronized (connectAcceptInterest) { connectAcceptInterest.add(selectorData); } @@ -839,11 +839,11 @@ public class NioThread implements Runnab // -------------- Housekeeping ------------- /** - * Same as APR connector - iterate over tasks, get + * Same as APR connector - iterate over tasks, get * smallest timeout - * @throws IOException + * @throws IOException */ - void updateSleepTimeAndProcessTimeouts(long now) + void updateSleepTimeAndProcessTimeouts(long now) throws IOException { long min = Long.MAX_VALUE; // TODO: test with large sets, maybe sort @@ -854,7 +854,7 @@ public class NioThread implements Runnab NioChannel selectorData = activeIt.next(); if (! selectorData.channel.isOpen()) { if (debug) { - log.info("Found closed socket, removing " + + log.info("Found closed socket, removing " + selectorData.channel); } // activeIt.remove(); @@ -892,18 +892,18 @@ public class NioThread implements Runnab nextWakeup = now + sleepTime; } - /** - * Request a callback whenever data can be written. - * When the callback is invoked, the write interest is removed ( to avoid + /** + * Request a callback whenever data can be written. + * When the callback is invoked, the write interest is removed ( to avoid * looping ). If the write() operation doesn't complete, you must call * writeInterest - AND stop writing, some implementations will throw - * exception. write() will actually attempt to detect this and avoid the + * exception. write() will actually attempt to detect this and avoid the * error. - * + * * @param sc */ public void writeInterest(NioChannel selectorData) { - // TODO: suspended ? + // TODO: suspended ? SelectionKey sk = (SelectionKey) selectorData.selKey; if (!sk.isValid()) { @@ -915,9 +915,9 @@ public class NioThread implements Runnab return; } if (Thread.currentThread() == selectorThread) { - interest = + interest = interest | SelectionKey.OP_WRITE; - sk.interestOps(interest); + sk.interestOps(interest); if (debug) { log.info("Write interest " + selectorData + " i=" + interest); } @@ -931,11 +931,11 @@ public class NioThread implements Runnab } selector.wakeup(); } - - + + public void readInterest(NioChannel selectorData, boolean b) throws IOException { if (Thread.currentThread() == selectorThread) { - selectorData.readInterest = b; + selectorData.readInterest = b; selThreadReadInterest(selectorData); return; } @@ -970,12 +970,12 @@ public class NioThread implements Runnab if (debug) { log.info("Register again for read interest"); } - SocketChannel socketChannel = + SocketChannel socketChannel = (SocketChannel) selectorData.channel; if (socketChannel.isOpen()) { selectorData.sel = this; - selectorData.selKey = - socketChannel.register(selector, + selectorData.selKey = + socketChannel.register(selector, SelectionKey.OP_READ, selectorData); selectorData.channel = socketChannel; } @@ -991,14 +991,14 @@ public class NioThread implements Runnab // if ((interest | SelectionKey.OP_READ) != 0) { // return; // } - interest = + interest = interest | SelectionKey.OP_READ; } else { // if ((interest | SelectionKey.OP_READ) == 0) { // return; // } - interest = - interest & ~SelectionKey.OP_READ; + interest = + interest & ~SelectionKey.OP_READ; } if (interest == 0) { if (!selectorData.inClosed) { @@ -1013,13 +1013,13 @@ public class NioThread implements Runnab sk.interestOps(interest); } if (debug) { - log.info(((selectorData.readInterest) - ? "RESUME read " : "SUSPEND read ") + log.info(((selectorData.readInterest) + ? "RESUME read " : "SUSPEND read ") + selectorData); } } } - + private void processPendingConnectAccept() throws IOException { synchronized (connectAcceptInterest) { @@ -1027,18 +1027,18 @@ public class NioThread implements Runnab while (ci.hasNext()) { NioChannel selectorData = ci.next(); - + // Find host, port - initiate connection try { // Accept interest ? if (selectorData.channel instanceof ServerSocketChannel) { - ServerSocketChannel socketChannel = + ServerSocketChannel socketChannel = (ServerSocketChannel) selectorData.channel; selectorData.sel = this; - selectorData.selKey = - socketChannel.register(selector, + selectorData.selKey = + socketChannel.register(selector, SelectionKey.OP_ACCEPT, selectorData); - + selectorData.channel = socketChannel; synchronized (active) { active.add(selectorData); @@ -1050,8 +1050,8 @@ public class NioThread implements Runnab SocketChannel socketChannel = (SocketChannel) selectorData.channel; selectorData.sel = this; - selectorData.selKey = - socketChannel.register(selector, + selectorData.selKey = + socketChannel.register(selector, SelectionKey.OP_CONNECT, selectorData); synchronized (active) { active.add(selectorData); @@ -1061,22 +1061,22 @@ public class NioThread implements Runnab } } } catch (Throwable e) { - log.log(Level.SEVERE, "error registering connect/accept", + log.log(Level.SEVERE, "error registering connect/accept", e); } } connectAcceptInterest.clear(); } } - + private void processPending() throws IOException { if (closeInterest.size() > 0) { synchronized (closeInterest) { List closeList = new ArrayList(closeInterest); closeInterest.clear(); - + Iterator ci = closeList.iterator(); - + while (ci.hasNext()) { try { NioChannel selectorData = ci.next(); @@ -1089,7 +1089,7 @@ public class NioThread implements Runnab } processPendingConnectAccept(); processPendingReadWrite(); - + if (runnableInterest.size() > 0) { synchronized (runnableInterest) { Iterator ci = runnableInterest.iterator(); @@ -1111,7 +1111,7 @@ public class NioThread implements Runnab } private void processPendingReadWrite() throws IOException { - // Update interest + // Update interest if (readInterest.size() > 0) { synchronized (readInterest) { Iterator ci = readInterest.iterator(); @@ -1145,10 +1145,10 @@ public class NioThread implements Runnab protected boolean isSelectorThread() { return Thread.currentThread() == selectorThread; } - + public static boolean isSelectorThread(IOChannel ch) { SocketIOChannel sc = (SocketIOChannel) ch.getFirst(); return Thread.currentThread() == sc.ch.sel.selectorThread; } - + } \ No newline at end of file Modified: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/SocketConnector.java URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/SocketConnector.java?rev=1187812&r1=1187811&r2=1187812&view=diff ============================================================================== --- tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/SocketConnector.java (original) +++ tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/SocketConnector.java Sat Oct 22 21:30:59 2011 @@ -14,28 +14,28 @@ import org.apache.tomcat.lite.io.NioChan /** * Class for handling sockets. It manages a pool of SelectorThreads, fully * non-blocking. There is no caching or buffer management. SelectorChannel - * represents on connection. - * + * represents on connection. + * * In the old types, the connector was socket-centric, and quite ugly. After * many refactoring the buffers ( buckets and brigade ) and callbacks are * used everywhere, and the sockets play a supporting role. - * - * TODO: discover if APR is available and use it, or fall back to NIO. - * + * + * TODO: discover if APR is available and use it, or fall back to NIO. + * * @author Costin Manolache */ public class SocketConnector extends IOConnector { static Logger log = Logger.getLogger(SocketConnector.class.getName()); static boolean debug = false; - + // TODO: pool, balanced usage - // TODO: bind into OM or callback when created + // TODO: bind into OM or callback when created private NioThread selector; - + // For resolving DNS ( i.e. connect ) Executor threadPool = Executors.newCachedThreadPool(); - + public SocketConnector() { timer = new Timer(true); } @@ -49,7 +49,7 @@ public class SocketConnector extends IOC * If the IP address is provided - it shouldn't block. */ @Override - public void connect(final String host, final int port, + public void connect(final String host, final int port, final IOConnector.ConnectedCallback sc) throws IOException { final SocketIOChannel ioch = new SocketIOChannel(this, null, host + ":" + port); ioch.setConnectedCallback(sc); @@ -70,15 +70,15 @@ public class SocketConnector extends IOC } }); } - + /** - * Create a new server socket, register the callback. + * Create a new server socket, register the callback. * If port == 0 it'll use the inherited channel, i.e. inetd mode. * TODO: if port == -1, detect a free port. May block. */ - public void acceptor(final IOConnector.ConnectedCallback sc, + public void acceptor(final IOConnector.ConnectedCallback sc, final CharSequence address, Object extra) - throws IOException + throws IOException { final int port = Integer.parseInt(address.toString()); NioChannelCallback acceptCb = new NioChannelCallback() { @@ -88,7 +88,7 @@ public class SocketConnector extends IOC @Override public void handleConnected(NioChannel ch) throws IOException { - SocketIOChannel ioch = new SocketIOChannel(SocketConnector.this, + SocketIOChannel ioch = new SocketIOChannel(SocketConnector.this, ch, ":" + port); sc.handleConnected(ioch); } @@ -101,11 +101,11 @@ public class SocketConnector extends IOC public void handleWriteable(NioChannel ch) throws IOException { } }; - + if (port == -1) { // TODO: find an unused port } else if (port == 0) { - getSelector().inetdAcceptor(acceptCb); + getSelector().inetdAcceptor(acceptCb); } else { getSelector().acceptor(acceptCb, port, null, 200, 20000); } @@ -121,12 +121,12 @@ public class SocketConnector extends IOC return selector; } - + public void stop() { getSelector().stop(); } // TODO: suspendAccept(boolean) - + } Modified: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/SocketIOChannel.java URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/SocketIOChannel.java?rev=1187812&r1=1187811&r2=1187812&view=diff ============================================================================== --- tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/SocketIOChannel.java (original) +++ tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/SocketIOChannel.java Sat Oct 22 21:30:59 2011 @@ -14,10 +14,10 @@ import org.apache.tomcat.lite.io.NioChan public class SocketIOChannel extends IOChannel implements NioChannelCallback { IOBuffer out; IOBuffer in; - + NioChannel ch; - - SocketIOChannel(IOConnector connector, NioChannel data, + + SocketIOChannel(IOConnector connector, NioChannel data, String target) throws IOException { this.connector = connector; @@ -35,8 +35,8 @@ public class SocketIOChannel extends IOC ch.callback = this; } } - - + + @Override public IOBuffer getIn() { return in; @@ -46,15 +46,15 @@ public class SocketIOChannel extends IOC public IOBuffer getOut() { return out; } - - /** + + /** * Both in and out open */ public boolean isOpen() { if (ch == null) { return false; } - return ch.isOpen() && ch.channel != null && + return ch.isOpen() && ch.channel != null && ch.channel.isOpen() && !getIn().isAppendClosed() && !getOut().isAppendClosed(); } @@ -66,16 +66,16 @@ public class SocketIOChannel extends IOC public String toString() { return ch.toString(); } - + public void setOutBuffer(IOBuffer out) { this.out = out; } - + ByteBuffer flushBuffer; /** - * Send as much as possible. - * + * Send as much as possible. + * * Adjust write interest so we can send more when possible. */ private void flush(NioChannel ch) throws IOException { @@ -91,13 +91,13 @@ public class SocketIOChannel extends IOC ch.shutdownOutput(); break; } - BBucket bb = out.peekFirst(); + BBucket bb = out.peekFirst(); if (bb == null) { break; } flushBuffer = getReadableBuffer(flushBuffer, bb); int before = flushBuffer.position(); - + int done = 0; while (flushBuffer.remaining() > 0) { try { @@ -126,19 +126,19 @@ public class SocketIOChannel extends IOC } } - + /** * Data available for read, called from IO thread. * You MUST read all data ( i.e. until read() returns 0). - * - * OP_READ remain active - call readInterest(false) to disable - + * + * OP_READ remain active - call readInterest(false) to disable - * for example to suspend reading if buffer is full. */ public void handleReceived(IOChannel net) throws IOException { // All data will go to currentReceiveBuffer, until it's full. // Then a new buffer will be allocated/pooled. - - // When we fill the buffers or finish this round of reading - + + // When we fill the buffers or finish this round of reading - // we place the Buckets in the queue, as 'readable' buffers. boolean newData = false; try { @@ -153,15 +153,15 @@ public class SocketIOChannel extends IOC newData = true; break; } - + ByteBuffer bb = in.getWriteBuffer(); read = ch.read(bb); in.releaseWriteBuffer(read); - + if (in == null) { // Detached. break; } - + if (read < 0) { // mark the in buffer as closed in.close(); @@ -179,7 +179,7 @@ public class SocketIOChannel extends IOC if (newData) { super.sendHandleReceivedCallback(); } - + } catch (Throwable t) { close(); if (t instanceof IOException) { @@ -198,7 +198,7 @@ public class SocketIOChannel extends IOC orig.limit(bucket.limit()); return orig; } - + public static final void releaseReadableBuffer(ByteBuffer bb, BBucket bucket) { bucket.position(bb.position()); } @@ -207,7 +207,7 @@ public class SocketIOChannel extends IOC public void readInterest(boolean b) throws IOException { ch.readInterest(b); } - + public InetAddress getAddress(boolean remote) { return ch.getAddress(remote); } @@ -215,19 +215,19 @@ public class SocketIOChannel extends IOC @Override public Object getAttribute(String name) { if (ATT_REMOTE_HOSTNAME.equals(name)) { - return getAddress(true).getHostName(); + return getAddress(true).getHostName(); } else if (ATT_LOCAL_HOSTNAME.equals(name)) { - return getAddress(false).getHostName(); + return getAddress(false).getHostName(); } else if (ATT_REMOTE_ADDRESS.equals(name)) { - return getAddress(true).getHostAddress(); + return getAddress(true).getHostAddress(); } else if (ATT_LOCAL_ADDRESS.equals(name)) { - return getAddress(false).getHostAddress(); + return getAddress(false).getHostAddress(); } else if (ATT_REMOTE_PORT.equals(name)) { return ch.getPort(true); } else if (ATT_LOCAL_PORT.equals(name)) { return ch.getPort(false); } - return null; + return null; } public void startSending() throws IOException { @@ -240,19 +240,19 @@ public class SocketIOChannel extends IOC startSending(); } } - + @Override public void handleClosed(NioChannel ch) throws IOException { lastException = ch.lastException; closed(); // our callback. } - + public void closed() throws IOException { getIn().close(); sendHandleReceivedCallback(); //super.closed(); } - + @Override public void handleConnected(NioChannel ch) throws IOException { setChannel(ch); Modified: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/SslProvider.java URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/SslProvider.java?rev=1187812&r1=1187811&r2=1187812&view=diff ============================================================================== --- tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/SslProvider.java (original) +++ tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/SslProvider.java Sat Oct 22 21:30:59 2011 @@ -11,14 +11,14 @@ public interface SslProvider { public static final String ATT_SSL_KEY_SIZE = "SslKeySize"; public static final String ATT_SSL_SESSION_ID = "SslSessionId"; - /** + /** * Wrap channel with SSL. - * - * The result will start a handshake + * + * The result will start a handshake */ - public IOChannel channel(IOChannel net, String host, int port) + public IOChannel channel(IOChannel net, String host, int port) throws IOException; public IOChannel serverChannel(IOChannel net) throws IOException; - + } Modified: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/UrlEncoding.java URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/UrlEncoding.java?rev=1187812&r1=1187811&r2=1187812&view=diff ============================================================================== --- tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/UrlEncoding.java (original) +++ tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/UrlEncoding.java Sat Oct 22 21:30:59 2011 @@ -25,12 +25,12 @@ import java.util.BitSet; /** * Support for %xx URL encoding. - * + * * @author Costin Manolache */ public final class UrlEncoding { - protected static final boolean ALLOW_ENCODED_SLASH = + protected static final boolean ALLOW_ENCODED_SLASH = Boolean.valueOf( System.getProperty( "org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH", @@ -44,10 +44,10 @@ public final class UrlEncoding { static BitSet SAFE_CHARS = new BitSet(128); BBuffer tmpBuffer = BBuffer.allocate(1024); CBuffer tmpCharBuffer = CBuffer.newInstance(); - + public void urlEncode(CBuffer url, CBuffer encoded, IOWriter enc) { tmpBuffer.recycle(); - urlEncode(url, tmpBuffer, encoded, enc.getEncoder("UTF-8"), + urlEncode(url, tmpBuffer, encoded, enc.getEncoder("UTF-8"), SAFE_CHARS_URL, true, enc); } @@ -56,9 +56,9 @@ public final class UrlEncoding { tmpCharBuffer.append(url); urlEncode(tmpCharBuffer, encoded, enc); } - + /** Only works for UTF-8 or charsets preserving ascii. - * + * * @param url * @param tmpBuffer * @param encoded @@ -72,7 +72,7 @@ public final class UrlEncoding { BitSet safeChars, boolean last, IOWriter enc) { // tomcat charset-encoded each character first. I don't think // this is needed. - + // TODO: space to + enc.encodeAll(url, tmpBuffer, utf8Enc, last); byte[] array = tmpBuffer.array(); @@ -89,13 +89,13 @@ public final class UrlEncoding { } } } - + static { initSafeChars(SAFE_CHARS); initSafeChars(SAFE_CHARS_URL); SAFE_CHARS_URL.set('/'); } - + private static void initSafeChars(BitSet safeChars) { int i; for (i = 'a'; i <= 'z'; i++) { @@ -121,12 +121,12 @@ public final class UrlEncoding { safeChars.set('$'); // ? safeChars.set('!'); // ? safeChars.set('\''); // ? - safeChars.set('('); // ? - safeChars.set(')'); // ? - safeChars.set(','); // ? + safeChars.set('('); // ? + safeChars.set(')'); // ? + safeChars.set(','); // ? } - - public void urlDecode(BBuffer bb, CBuffer dest, boolean q, + + public void urlDecode(BBuffer bb, CBuffer dest, boolean q, IOReader charDec) throws IOException { // Replace %xx tmpBuffer.append(bb); @@ -134,8 +134,8 @@ public final class UrlEncoding { charDec.decodeAll(bb, dest); } - - public void urlDecode(BBuffer bb, CBuffer dest, + + public void urlDecode(BBuffer bb, CBuffer dest, IOReader charDec) throws IOException { // Replace %xx tmpBuffer.append(bb); @@ -143,11 +143,11 @@ public final class UrlEncoding { charDec.decodeAll(bb, dest); } - + /** - * URLDecode, will modify the source. This is only at byte level - - * it needs conversion to chars using the right charset. - * + * URLDecode, will modify the source. This is only at byte level - + * it needs conversion to chars using the right charset. + * * @param query Converts '+' to ' ' and allow '/' */ public void urlDecode(BBuffer mb, boolean query) throws IOException { Modified: tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/WrappedException.java URL: http://svn.apache.org/viewvc/tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/WrappedException.java?rev=1187812&r1=1187811&r2=1187812&view=diff ============================================================================== --- tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/WrappedException.java (original) +++ tomcat/trunk/modules/tomcat-lite/java/org/apache/tomcat/lite/io/WrappedException.java Sat Oct 22 21:30:59 2011 @@ -6,8 +6,8 @@ import java.io.IOException; /** * For specific exceptions - also has cause ( good if compiling against - * JDK1.5 ) - * + * JDK1.5 ) + * * @author Costin Manolache */ public class WrappedException extends IOException { @@ -15,7 +15,7 @@ public class WrappedException extends IO public WrappedException() { super(); } - + public WrappedException(String message) { super(message); } @@ -24,17 +24,17 @@ public class WrappedException extends IO super(message); initCause(cause); } - + public WrappedException(Throwable cause) { super(""); initCause(cause); } - - + + public static class ClientAbortException extends WrappedException { public ClientAbortException(Throwable throwable) { super(null, throwable); } } - + } --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org For additional commands, e-mail: dev-help@tomcat.apache.org