< prev index next >

src/java.base/share/classes/java/io/BufferedInputStream.java

Print this page

        

*** 23,32 **** --- 23,33 ---- * questions. */ package java.io; + import java.util.concurrent.locks.ReentrantLock; import jdk.internal.misc.Unsafe; import jdk.internal.util.ArraysSupport; /** * A <code>BufferedInputStream</code> adds
*** 62,71 **** --- 63,75 ---- private static final Unsafe U = Unsafe.getUnsafe(); private static final long BUF_OFFSET = U.objectFieldOffset(BufferedInputStream.class, "buf"); + // initialized to null when BufferedInputStream is sub-classed + private final ReentrantLock lock; + /** * The internal buffer array where the data is stored. When necessary, * it may be replaced by another array of * a different size. */
*** 198,213 **** super(in); if (size <= 0) { throw new IllegalArgumentException("Buffer size <= 0"); } buf = new byte[size]; } /** * Fills the buffer with more data, taking into account * shuffling and other tricks for dealing with marks. ! * Assumes that it is being called by a synchronized method. * This method also assumes that all data has already been read in, * hence pos > count. */ private void fill() throws IOException { byte[] buffer = getBufIfOpen(); --- 202,224 ---- super(in); if (size <= 0) { throw new IllegalArgumentException("Buffer size <= 0"); } buf = new byte[size]; + + // use monitors when BufferedInputStream is sub-classed + if (getClass() == BufferedInputStream.class) { + lock = new ReentrantLock(); + } else { + lock = null; + } } /** * Fills the buffer with more data, taking into account * shuffling and other tricks for dealing with marks. ! * Assumes that it is being called by a locked method. * This method also assumes that all data has already been read in, * hence pos > count. */ private void fill() throws IOException { byte[] buffer = getBufIfOpen();
*** 257,267 **** * @exception IOException if this input stream has been closed by * invoking its {@link #close()} method, * or an I/O error occurs. * @see java.io.FilterInputStream#in */ ! public synchronized int read() throws IOException { if (pos >= count) { fill(); if (pos >= count) return -1; } --- 268,293 ---- * @exception IOException if this input stream has been closed by * invoking its {@link #close()} method, * or an I/O error occurs. * @see java.io.FilterInputStream#in */ ! public int read() throws IOException { ! if (lock != null) { ! lock.lock(); ! try { ! return lockedRead(); ! } finally { ! lock.unlock(); ! } ! } else { ! synchronized (this) { ! return lockedRead(); ! } ! } ! } ! ! private int lockedRead() throws IOException { if (pos >= count) { fill(); if (pos >= count) return -1; }
*** 327,339 **** * the stream has been reached. * @exception IOException if this input stream has been closed by * invoking its {@link #close()} method, * or an I/O error occurs. */ ! public synchronized int read(byte b[], int off, int len) ! throws IOException ! { getBufIfOpen(); // Check for closed stream if ((off | len | (off + len) | (b.length - (off + len))) < 0) { throw new IndexOutOfBoundsException(); } else if (len == 0) { return 0; --- 353,378 ---- * the stream has been reached. * @exception IOException if this input stream has been closed by * invoking its {@link #close()} method, * or an I/O error occurs. */ ! public int read(byte b[], int off, int len) throws IOException { ! if (lock != null) { ! lock.lock(); ! try { ! return lockedRead(b, off, len); ! } finally { ! lock.unlock(); ! } ! } else { ! synchronized (this) { ! return lockedRead(b, off, len); ! } ! } ! } ! ! private int lockedRead(byte b[], int off, int len) throws IOException { getBufIfOpen(); // Check for closed stream if ((off | len | (off + len) | (b.length - (off + len))) < 0) { throw new IndexOutOfBoundsException(); } else if (len == 0) { return 0;
*** 361,371 **** * @throws IOException if this input stream has been closed by * invoking its {@link #close()} method, * {@code in.skip(n)} throws an IOException, * or an I/O error occurs. */ ! public synchronized long skip(long n) throws IOException { getBufIfOpen(); // Check for closed stream if (n <= 0) { return 0; } long avail = count - pos; --- 400,425 ---- * @throws IOException if this input stream has been closed by * invoking its {@link #close()} method, * {@code in.skip(n)} throws an IOException, * or an I/O error occurs. */ ! public long skip(long n) throws IOException { ! if (lock != null) { ! lock.lock(); ! try { ! return lockedSkip(n); ! } finally { ! lock.unlock(); ! } ! } else { ! synchronized (this) { ! return lockedSkip(n); ! } ! } ! } ! ! private long lockedSkip(long n) throws IOException { getBufIfOpen(); // Check for closed stream if (n <= 0) { return 0; } long avail = count - pos;
*** 402,412 **** * over) from this input stream without blocking. * @exception IOException if this input stream has been closed by * invoking its {@link #close()} method, * or an I/O error occurs. */ ! public synchronized int available() throws IOException { int n = count - pos; int avail = getInIfOpen().available(); return n > (Integer.MAX_VALUE - avail) ? Integer.MAX_VALUE : n + avail; --- 456,481 ---- * over) from this input stream without blocking. * @exception IOException if this input stream has been closed by * invoking its {@link #close()} method, * or an I/O error occurs. */ ! public int available() throws IOException { ! if (lock != null) { ! lock.lock(); ! try { ! return lockAvailable(); ! } finally { ! lock.unlock(); ! } ! } else { ! synchronized (this) { ! return lockAvailable(); ! } ! } ! } ! ! private int lockAvailable() throws IOException { int n = count - pos; int avail = getInIfOpen().available(); return n > (Integer.MAX_VALUE - avail) ? Integer.MAX_VALUE : n + avail;
*** 418,428 **** * * @param readlimit the maximum limit of bytes that can be read before * the mark position becomes invalid. * @see java.io.BufferedInputStream#reset() */ ! public synchronized void mark(int readlimit) { marklimit = readlimit; markpos = pos; } /** --- 487,512 ---- * * @param readlimit the maximum limit of bytes that can be read before * the mark position becomes invalid. * @see java.io.BufferedInputStream#reset() */ ! public void mark(int readlimit) { ! if (lock != null) { ! lock.lock(); ! try { ! lockedMark(readlimit); ! } finally { ! lock.unlock(); ! } ! } else { ! synchronized (this) { ! lockedMark(readlimit); ! } ! } ! } ! ! private void lockedMark(int readlimit) { marklimit = readlimit; markpos = pos; } /**
*** 439,449 **** * if the mark has been invalidated, or the stream * has been closed by invoking its {@link #close()} * method, or an I/O error occurs. * @see java.io.BufferedInputStream#mark(int) */ ! public synchronized void reset() throws IOException { getBufIfOpen(); // Cause exception if closed if (markpos < 0) throw new IOException("Resetting to invalid mark"); pos = markpos; } --- 523,548 ---- * if the mark has been invalidated, or the stream * has been closed by invoking its {@link #close()} * method, or an I/O error occurs. * @see java.io.BufferedInputStream#mark(int) */ ! public void reset() throws IOException { ! if (lock != null) { ! lock.lock(); ! try { ! lockedReset(); ! } finally { ! lock.unlock(); ! } ! } else { ! synchronized (this) { ! lockedReset(); ! } ! } ! } ! ! private void lockedReset() throws IOException { getBufIfOpen(); // Cause exception if closed if (markpos < 0) throw new IOException("Resetting to invalid mark"); pos = markpos; }
< prev index next >