src/java.base/share/classes/sun/net/www/MeteredStream.java
branchJDK-8229867-branch
changeset 57968 8595871a5446
parent 47216 71c04702a3d5
--- a/src/java.base/share/classes/sun/net/www/MeteredStream.java	Fri Aug 30 13:11:16 2019 +0100
+++ b/src/java.base/share/classes/sun/net/www/MeteredStream.java	Fri Aug 30 15:42:27 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 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,8 @@
 
 package sun.net.www;
 
-import java.net.URL;
-import java.util.*;
 import java.io.*;
+import java.util.concurrent.locks.ReentrantLock;
 import sun.net.ProgressSource;
 import sun.net.www.http.ChunkedInputStream;
 
@@ -44,6 +43,7 @@
     protected long markedCount = 0;
     protected int markLimit = -1;
     protected ProgressSource pi;
+    protected final ReentrantLock readLock = new ReentrantLock();
 
     public MeteredStream(InputStream is, ProgressSource pi, long expected)
     {
@@ -57,7 +57,9 @@
         }
     }
 
-    private final void justRead(long n) throws IOException   {
+    private final  void justRead(long n) throws IOException   {
+        assert readLock.isHeldByCurrentThread();
+
         if (n == -1) {
 
             /*
@@ -99,6 +101,7 @@
      * Returns true if the mark is valid, false otherwise
      */
     private boolean isMarked() {
+        assert readLock.isHeldByCurrentThread();
 
         if (markLimit < 0) {
             return false;
@@ -113,94 +116,128 @@
         return true;
     }
 
-    public synchronized int read() throws java.io.IOException {
-        if (closed) {
-            return -1;
+    public int read() throws java.io.IOException {
+        if (closed) return -1;
+        readLock.lock();
+        try {
+            if (closed) return -1;
+            int c = in.read();
+            if (c != -1) {
+                justRead(1);
+            } else {
+                justRead(c);
+            }
+            return c;
+        } finally {
+            readLock.unlock();
         }
-        int c = in.read();
-        if (c != -1) {
-            justRead(1);
-        } else {
-            justRead(c);
-        }
-        return c;
     }
 
-    public synchronized int read(byte b[], int off, int len)
+    public int read(byte b[], int off, int len)
                 throws java.io.IOException {
-        if (closed) {
-            return -1;
+        if (closed) return -1;
+        readLock.lock();
+        try {
+            if (closed) return -1;
+
+            int n = in.read(b, off, len);
+            justRead(n);
+            return n;
+        } finally {
+            readLock.unlock();
         }
-        int n = in.read(b, off, len);
-        justRead(n);
-        return n;
     }
 
-    public synchronized long skip(long n) throws IOException {
+    public long skip(long n) throws IOException {
 
-        // REMIND: what does skip do on EOF????
-        if (closed) {
-            return 0;
-        }
+        if (closed) return 0;
+        readLock.lock();
+        try {
+            // REMIND: what does skip do on EOF????
+            if (closed) return 0;
 
-        if (in instanceof ChunkedInputStream) {
-            n = in.skip(n);
+            if (in instanceof ChunkedInputStream) {
+                n = in.skip(n);
+            } else {
+                // just skip min(n, num_bytes_left)
+                long min = (n > expected - count) ? expected - count : n;
+                n = in.skip(min);
+            }
+            justRead(n);
+            return n;
+        } finally {
+            readLock.unlock();
         }
-        else {
-            // just skip min(n, num_bytes_left)
-            long min = (n > expected - count) ? expected - count: n;
-            n = in.skip(min);
-        }
-        justRead(n);
-        return n;
     }
 
     public void close() throws IOException {
-        if (closed) {
-            return;
+        if (closed) return;
+        readLock.lock();
+        try {
+            if (closed) return;
+            if (pi != null)
+                pi.finishTracking();
+
+            closed = true;
+            in.close();
+        } finally {
+            readLock.unlock();
         }
-        if (pi != null)
-            pi.finishTracking();
-
-        closed = true;
-        in.close();
     }
 
-    public synchronized int available() throws IOException {
-        return closed ? 0: in.available();
+    public int available() throws IOException {
+        if (closed) return 0;
+        readLock.lock();
+        try {
+            return closed ? 0 : in.available();
+        } finally {
+            readLock.unlock();
+        }
     }
 
-    public synchronized void mark(int readLimit) {
-        if (closed) {
-            return;
-        }
-        super.mark(readLimit);
+    public void mark(int readLimit) {
+        if (closed) return;
+        readLock.lock();
+        try {
+            if (closed) return;
+            super.mark(readLimit);
 
-        /*
-         * mark the count to restore upon reset
-         */
-        markedCount = count;
-        markLimit = readLimit;
+            /*
+             * mark the count to restore upon reset
+             */
+            markedCount = count;
+            markLimit = readLimit;
+        } finally {
+            readLock.unlock();
+        }
     }
 
-    public synchronized void reset() throws IOException {
-        if (closed) {
-            return;
-        }
+    public void reset() throws IOException {
+        if (closed) return;
 
-        if (!isMarked()) {
-            throw new IOException ("Resetting to an invalid mark");
+        readLock.lock();
+        try {
+            if (closed) return;
+            if (!isMarked()) {
+                throw new IOException("Resetting to an invalid mark");
+            }
+
+            count = markedCount;
+            super.reset();
+        } finally {
+            readLock.unlock();
         }
-
-        count = markedCount;
-        super.reset();
     }
 
     public boolean markSupported() {
-        if (closed) {
-            return false;
+        if (closed) return false;
+        readLock.lock();
+        try {
+            if (closed) return false;
+            return super.markSupported();
+        } finally {
+            readLock.unlock();
         }
-        return super.markSupported();
     }
 
     @SuppressWarnings("deprecation")