Skip to content

Commit

Permalink
Since nobody seems to object for now, pull up NIO2 style API and add …
Browse files Browse the repository at this point in the history
…stubs for APR and NIO.

git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@1674070 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information
rmaucher committed Apr 16, 2015
1 parent 064cfe5 commit bdbbac0
Show file tree
Hide file tree
Showing 4 changed files with 263 additions and 201 deletions.
28 changes: 28 additions & 0 deletions java/org/apache/tomcat/util/net/AprEndpoint.java
Expand Up @@ -20,6 +20,7 @@
import java.io.IOException; import java.io.IOException;
import java.net.SocketTimeoutException; import java.net.SocketTimeoutException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.channels.CompletionHandler;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
Expand All @@ -28,6 +29,7 @@
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
Expand Down Expand Up @@ -2892,5 +2894,31 @@ public void doClientAuth(SSLSupport sslSupport) {
((AprEndpoint)getEndpoint()).getSSLVerifyDepth()); ((AprEndpoint)getEndpoint()).getSSLVerifyDepth());
SSLSocket.renegotiate(socket); SSLSocket.renegotiate(socket);
} }


@Override
public boolean isWritePending() {
return false;
}


@Override
public <A> CompletionState read(ByteBuffer[] dsts, int offset,
int length, boolean block, long timeout, TimeUnit unit,
A attachment, CompletionCheck check,
CompletionHandler<Long, ? super A> handler) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException();
}

@Override
public <A> CompletionState write(ByteBuffer[] srcs, int offset,
int length, boolean block, long timeout, TimeUnit unit,
A attachment, CompletionCheck check,
CompletionHandler<Long, ? super A> handler) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException();
}

} }
} }
204 changes: 3 additions & 201 deletions java/org/apache/tomcat/util/net/Nio2Endpoint.java
Expand Up @@ -957,59 +957,6 @@ public void close() throws IOException {
} }
} }


// TODO: NIO2 style scatter/gather methods.

public enum CompletionState {
/**
* Operation is still pending.
*/
PENDING,
/**
* The operation completed inline.
*/
INLINE,
/**
* The operation completed, but not inline.
*/
DONE
}

public enum CompletionHandlerCall {
/**
* Operation should continue, the completion handler shouldn't be
* called.
*/
CONTINUE,
/**
* The operation completed but the completion handler shouldn't be
* called.
*/
NONE,
/**
* The operation is complete, the completion handler should be
* called.
*/
DONE
}

public interface CompletionCheck {
/**
* Return true if enough data has been read or written and the
* handler should be notified. Return false if the IO is
* incomplete (data has not been fully written while it should,
* or more data read is needed for further processing) and should
* be continued before the completion handler is called.
*
* @param state of the operation (done or done inline since the
* IO call is done)
* @param buffers ByteBuffer[] that has been passed to the
* original IO call
* @param offset that has been passed to the original IO call
* @param length that has been passed to the original IO call
*/
public CompletionHandlerCall callHandler(CompletionState state, ByteBuffer[] buffers, int offset, int length);
}

/** /**
* Internal state tracker for scatter/gather operations. * Internal state tracker for scatter/gather operations.
*/ */
Expand Down Expand Up @@ -1140,92 +1087,7 @@ public void failed(Throwable exc, OperationState<A> state) {
} }
} }


/** @Override
* This utility CompletionCheck will cause the write to fully write
* all remaining data. If the operation completes inline, the
* completion handler will not be called.
*/
public static final CompletionCheck COMPLETE_WRITE = new CompletionCheck() {
@Override
public CompletionHandlerCall callHandler(CompletionState state, ByteBuffer[] buffers, int offset, int length) {
for (int i = 0; i < offset; i++) {
if (buffers[i].remaining() > 0) {
return CompletionHandlerCall.CONTINUE;
}
}
return (state == CompletionState.DONE) ? CompletionHandlerCall.DONE : CompletionHandlerCall.NONE;
}
};

/**
* This utility CompletionCheck will cause the completion handler
* to be called once some data has been read. If the operation
* completes inline, the completion handler will not be called.
*/
public static final CompletionCheck READ_DATA = new CompletionCheck() {
@Override
public CompletionHandlerCall callHandler(CompletionState state, ByteBuffer[] buffers, int offset, int length) {
return (state == CompletionState.DONE) ? CompletionHandlerCall.DONE : CompletionHandlerCall.NONE;
}
};

/**
* Scatter read. The completion handler will be called once some
* data has been read or an error occurred. If a CompletionCheck
* object has been provided, the completion handler will only be
* called if the callHandler method returned true. If no
* CompletionCheck object has been provided, the ddefault NIO2
* behavior is used: the completion handler will be called as soon
* as some data has been read, even if the read has completed inline.
*
* @param block true to block until any pending read is done, if the
* timeout occurs and a read is still pending, a
* ReadPendingException will be thrown; false to
* not block but any pending read operation will cause
* a ReadPendingException
* @param timeout
* @param unit
* @param attachment
* @param check for the IO operation completion
* @param handler to call when the IO is complete
* @param dsts buffers
* @return the completion state (done, done inline, or still pending)
*/
// FIXME: @Override
public <A> CompletionState read(boolean block, long timeout, TimeUnit unit, A attachment,
CompletionCheck check, CompletionHandler<Long, ? super A> handler,
ByteBuffer... dsts) {
if (dsts == null) {
throw new IllegalArgumentException();
}
return read(dsts, 0, dsts.length, block, timeout, unit, attachment, check, handler);
}

/**
* Scatter read. The completion handler will be called once some
* data has been read or an error occurred. If a CompletionCheck
* object has been provided, the completion handler will only be
* called if the callHandler method returned true. If no
* CompletionCheck object has been provided, the ddefault NIO2
* behavior is used: the completion handler will be called as soon
* as some data has been read, even if the read has completed inline.
*
* @param dsts buffers
* @param offset in the buffer array
* @param length in the buffer array
* @param block true to block until any pending read is done, if the
* timeout occurs and a read is still pending, a
* ReadPendingException will be thrown; false to
* not block but any pending read operation will cause
* a ReadPendingException
* @param timeout
* @param unit
* @param attachment
* @param check for the IO operation completion
* @param handler to call when the IO is complete
* @return the completion state (done, done inline, or still pending)
*/
// FIXME: @Override
public <A> CompletionState read(ByteBuffer[] dsts, int offset, int length, public <A> CompletionState read(ByteBuffer[] dsts, int offset, int length,
boolean block, long timeout, TimeUnit unit, A attachment, boolean block, long timeout, TimeUnit unit, A attachment,
CompletionCheck check, CompletionHandler<Long, ? super A> handler) { CompletionCheck check, CompletionHandler<Long, ? super A> handler) {
Expand All @@ -1244,72 +1106,14 @@ public <A> CompletionState read(ByteBuffer[] dsts, int offset, int length,
return state.state; return state.state;
} }


// FIXME: @Override @Override
public boolean isWritePending() { public boolean isWritePending() {
synchronized (writeCompletionHandler) { synchronized (writeCompletionHandler) {
return writePending.availablePermits() == 0; return writePending.availablePermits() == 0;
} }
} }


/** @Override
* Gather write. The completion handler will be called once some
* data has been written or an error occurred. If a CompletionCheck
* object has been provided, the completion handler will only be
* called if the callHandler method returned true. If no
* CompletionCheck object has been provided, the ddefault NIO2
* behavior is used: the completion handler will be called, even
* if the write is incomplete and data remains in the buffers, or
* if the write completed inline.
*
* @param block true to block until any pending write is done, if the
* timeout occurs and a write is still pending, a
* WritePendingException will be thrown; false to
* not block but any pending write operation will cause
* a WritePendingException
* @param timeout
* @param unit
* @param attachment
* @param check for the IO operation completion
* @param handler to call when the IO is complete
* @param srcs buffers
* @return the completion state (done, done inline, or still pending)
*/
// FIXME: @Override
public <A> CompletionState write(boolean block, long timeout, TimeUnit unit, A attachment,
CompletionCheck check, CompletionHandler<Long, ? super A> handler,
ByteBuffer... srcs) {
if (srcs == null) {
throw new IllegalArgumentException();
}
return write(srcs, 0, srcs.length, block, timeout, unit, attachment, check, handler);
}

/**
* Gather write. The completion handler will be called once some
* data has been written or an error occurred. If a CompletionCheck
* object has been provided, the completion handler will only be
* called if the callHandler method returned true. If no
* CompletionCheck object has been provided, the ddefault NIO2
* behavior is used: the completion handler will be called, even
* if the write is incomplete and data remains in the buffers, or
* if the write completed inline.
*
* @param srcs buffers
* @param offset in the buffer array
* @param length in the buffer array
* @param block true to block until any pending write is done, if the
* timeout occurs and a write is still pending, a
* WritePendingException will be thrown; false to
* not block but any pending write operation will cause
* a WritePendingException
* @param timeout
* @param unit
* @param attachment
* @param check for the IO operation completion
* @param handler to call when the IO is complete
* @return the completion state (done, done inline, or still pending)
*/
// FIXME: @Override
public <A> CompletionState write(ByteBuffer[] srcs, int offset, int length, public <A> CompletionState write(ByteBuffer[] srcs, int offset, int length,
boolean block, long timeout, TimeUnit unit, A attachment, boolean block, long timeout, TimeUnit unit, A attachment,
CompletionCheck check, CompletionHandler<Long, ? super A> handler) { CompletionCheck check, CompletionHandler<Long, ? super A> handler) {
Expand All @@ -1328,8 +1132,6 @@ public <A> CompletionState write(ByteBuffer[] srcs, int offset, int length,
return state.state; return state.state;
} }


// TODO: End NIO2 style scatter/gather methods.

/* Callers of this method must: /* Callers of this method must:
* - have acquired the readPending semaphore * - have acquired the readPending semaphore
* - have acquired a lock on readCompletionHandler * - have acquired a lock on readCompletionHandler
Expand Down
24 changes: 24 additions & 0 deletions java/org/apache/tomcat/util/net/NioEndpoint.java
Expand Up @@ -26,6 +26,7 @@
import java.net.SocketTimeoutException; import java.net.SocketTimeoutException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.channels.CancelledKeyException; import java.nio.channels.CancelledKeyException;
import java.nio.channels.CompletionHandler;
import java.nio.channels.FileChannel; import java.nio.channels.FileChannel;
import java.nio.channels.SelectionKey; import java.nio.channels.SelectionKey;
import java.nio.channels.Selector; import java.nio.channels.Selector;
Expand Down Expand Up @@ -1499,6 +1500,29 @@ public void doClientAuth(SSLSupport sslSupport) {
} }
} }
} }

@Override
public boolean isWritePending() {
return false;
}

@Override
public <A> CompletionState read(ByteBuffer[] dsts, int offset,
int length, boolean block, long timeout, TimeUnit unit,
A attachment, CompletionCheck check,
CompletionHandler<Long, ? super A> handler) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException();
}

@Override
public <A> CompletionState write(ByteBuffer[] srcs, int offset,
int length, boolean block, long timeout, TimeUnit unit,
A attachment, CompletionCheck check,
CompletionHandler<Long, ? super A> handler) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException();
}
} }




Expand Down

0 comments on commit bdbbac0

Please sign in to comment.