src/java.base/share/classes/sun/net/www/http/ChunkedInputStream.java
branchJDK-8229867-branch
changeset 57968 8595871a5446
parent 47216 71c04702a3d5
--- 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);
     }
 
 }