--- 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")