--- a/src/java.base/share/classes/sun/net/www/http/ChunkedInputStream.java Fri Aug 30 13:11:16 2019 +0100
+++ b/src/java.base/share/classes/sun/net/www/http/ChunkedInputStream.java Fri Aug 30 15:42:27 2019 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,9 +25,7 @@
package sun.net.www.http;
import java.io.*;
-import java.util.*;
-
-import sun.net.*;
+import java.util.concurrent.locks.ReentrantLock;
import sun.net.www.*;
/**
@@ -40,8 +38,7 @@
* can be hurried to the end of the stream if the bytes are available on
* the underlying stream.
*/
-public
-class ChunkedInputStream extends InputStream implements Hurryable {
+public class ChunkedInputStream extends InputStream implements Hurryable {
/**
* The underlying stream
@@ -125,11 +122,14 @@
*/
private boolean closed;
+ final ReentrantLock readLock = new ReentrantLock();
+
/*
* Maximum chunk header size of 2KB + 2 bytes for CRLF
*/
private static final int MAX_CHUNK_HEADER_SIZE = 2050;
+
/**
* State to indicate that next field should be :-
* chunk-size [ chunk-extension ] CRLF
@@ -645,14 +645,19 @@
* @exception IOException if an I/O error occurs.
* @see java.io.FilterInputStream#in
*/
- public synchronized int read() throws IOException {
- ensureOpen();
- if (chunkPos >= chunkCount) {
- if (readAhead(true) <= 0) {
- return -1;
+ public int read() throws IOException {
+ readLock.lock();
+ try {
+ ensureOpen();
+ if (chunkPos >= chunkCount) {
+ if (readAhead(true) <= 0) {
+ return -1;
+ }
}
+ return chunkData[chunkPos++] & 0xff;
+ } finally {
+ readLock.unlock();
}
- return chunkData[chunkPos++] & 0xff;
}
@@ -667,42 +672,47 @@
* the stream has been reached.
* @exception IOException if an I/O error occurs.
*/
- public synchronized int read(byte b[], int off, int len)
+ public int read(byte b[], int off, int len)
throws IOException
{
- ensureOpen();
- if ((off < 0) || (off > b.length) || (len < 0) ||
- ((off + len) > b.length) || ((off + len) < 0)) {
- throw new IndexOutOfBoundsException();
- } else if (len == 0) {
- return 0;
- }
-
- int avail = chunkCount - chunkPos;
- if (avail <= 0) {
- /*
- * Optimization: if we're in the middle of the chunk read
- * directly from the underlying stream into the caller's
- * buffer
- */
- if (state == STATE_READING_CHUNK) {
- return fastRead( b, off, len );
+ readLock.lock();
+ try {
+ ensureOpen();
+ if ((off < 0) || (off > b.length) || (len < 0) ||
+ ((off + len) > b.length) || ((off + len) < 0)) {
+ throw new IndexOutOfBoundsException();
+ } else if (len == 0) {
+ return 0;
}
- /*
- * We're not in the middle of a chunk so we must read ahead
- * until there is some chunk data available.
- */
- avail = readAhead(true);
- if (avail < 0) {
- return -1; /* EOF */
+ int avail = chunkCount - chunkPos;
+ if (avail <= 0) {
+ /*
+ * Optimization: if we're in the middle of the chunk read
+ * directly from the underlying stream into the caller's
+ * buffer
+ */
+ if (state == STATE_READING_CHUNK) {
+ return fastRead(b, off, len);
+ }
+
+ /*
+ * We're not in the middle of a chunk so we must read ahead
+ * until there is some chunk data available.
+ */
+ avail = readAhead(true);
+ if (avail < 0) {
+ return -1; /* EOF */
+ }
}
+ int cnt = (avail < len) ? avail : len;
+ System.arraycopy(chunkData, chunkPos, b, off, cnt);
+ chunkPos += cnt;
+
+ return cnt;
+ } finally {
+ readLock.unlock();
}
- int cnt = (avail < len) ? avail : len;
- System.arraycopy(chunkData, chunkPos, b, off, cnt);
- chunkPos += cnt;
-
- return cnt;
}
/**
@@ -714,20 +724,25 @@
* @exception IOException if an I/O error occurs.
* @see java.io.FilterInputStream#in
*/
- public synchronized int available() throws IOException {
- ensureOpen();
+ public int available() throws IOException {
+ readLock.lock();
+ try {
+ ensureOpen();
+
+ int avail = chunkCount - chunkPos;
+ if (avail > 0) {
+ return avail;
+ }
- int avail = chunkCount - chunkPos;
- if(avail > 0) {
- return avail;
- }
+ avail = readAhead(false);
- avail = readAhead(false);
-
- if (avail < 0) {
- return 0;
- } else {
- return avail;
+ if (avail < 0) {
+ return 0;
+ } else {
+ return avail;
+ }
+ } finally {
+ readLock.unlock();
}
}
@@ -742,12 +757,18 @@
*
* @exception IOException if an I/O error occurs.
*/
- public synchronized void close() throws IOException {
- if (closed) {
- return;
+ public void close() throws IOException {
+ if (closed) return;
+ readLock.lock();
+ try {
+ if (closed) {
+ return;
+ }
+ closeUnderlying();
+ closed = true;
+ } finally {
+ readLock.unlock();
}
- closeUnderlying();
- closed = true;
}
/**
@@ -759,22 +780,27 @@
* without blocking then this stream can't be hurried and should be
* closed.
*/
- public synchronized boolean hurry() {
- if (in == null || error) {
- return false;
- }
-
+ public boolean hurry() {
+ readLock.lock();
try {
- readAhead(false);
- } catch (Exception e) {
- return false;
- }
+ if (in == null || error) {
+ return false;
+ }
- if (error) {
- return false;
+ try {
+ readAhead(false);
+ } catch (Exception e) {
+ return false;
+ }
+
+ if (error) {
+ return false;
+ }
+
+ return (state == STATE_DONE);
+ } finally {
+ readLock.unlock();
}
-
- return (state == STATE_DONE);
}
}