MCPcopy Create free account
hub / github.com/apache/tomcat / StandardStreamInputBuffer

Class StandardStreamInputBuffer

java/org/apache/coyote/http2/Stream.java:1216–1542  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1214
1215
1216 class StandardStreamInputBuffer extends StreamInputBuffer {
1217
1218 private final Lock readStateLock = new ReentrantLock();
1219 /*
1220 * Two buffers are required to avoid various multi-threading issues. These issues arise from the fact that the
1221 * Stream (or the Request/Response) used by the application is processed in one thread but the connection is
1222 * processed in another. Therefore it is possible that a request body frame could be received before the
1223 * application is ready to read it. If it isn't buffered, processing of the connection (and hence all streams)
1224 * would block until the application read the data. Hence the incoming data has to be buffered. If only one
1225 * buffer was used then it could become corrupted if the connection thread is trying to add to it at the same
1226 * time as the application is read it. While it should be possible to avoid this corruption by careful use of
1227 * the buffer it would still require the same copies as using two buffers and the behaviour would be less clear.
1228 *
1229 * The buffers are created lazily because they quickly add up to a lot of memory and most requests do not have
1230 * bodies.
1231 */
1232 // This buffer is used to populate the ByteChunk passed in to the read
1233 // method
1234 private byte[] outBuffer;
1235 // This buffer is the destination for incoming data. It is normally is
1236 // 'write mode'.
1237 private volatile ByteBuffer inBuffer;
1238 private volatile boolean readInterest;
1239 // If readInterest is true, data must be available to read no later than this time.
1240 private volatile long readTimeoutExpiry;
1241 private volatile boolean closed;
1242 private volatile boolean resetReceived;
1243
1244 @Override
1245 public final int doRead(ApplicationBufferHandler applicationBufferHandler) throws IOException {
1246
1247 ensureBuffersExist();
1248
1249 int written;
1250
1251 // It is still possible that the stream has been closed and inBuffer
1252 // set to null between the call to ensureBuffersExist() above and
1253 // the sync below. The checks just before and just inside the sync
1254 // ensure we don't get any NPEs reported.
1255 ByteBuffer tmpInBuffer = inBuffer;
1256 if (tmpInBuffer == null) {
1257 return -1;
1258 }
1259 // Ensure that only one thread accesses inBuffer at a time
1260 synchronized (tmpInBuffer) {
1261 if (inBuffer == null) {
1262 return -1;
1263 }
1264 boolean canRead = false;
1265 while (inBuffer.position() == 0 && (canRead = isActive() && !isInputFinished())) {
1266 // Need to block until some data is written
1267 try {
1268 if (log.isTraceEnabled()) {
1269 log.trace(sm.getString("stream.inputBuffer.empty"));
1270 }
1271
1272 long readTimeout = handler.getProtocol().getStreamReadTimeout();
1273 if (readTimeout < 0) {

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected