< prev index next >

src/java.base/share/classes/jdk/internal/jimage/ImageReader.java

Print this page
rev 16699 : 8175010: ImageReader is not thread-safe
Reviewed-by: alanb

@@ -50,11 +50,13 @@
  * It is used internally in the JDK to implement jimage/jrtfs access,
  * but also compiled and delivered as part of the jrtfs.jar to support access
  * to the jimage file provided by the shipped JDK by tools running on JDK 8.
  */
 public final class ImageReader implements AutoCloseable {
-    private SharedImageReader reader;
+    private final SharedImageReader reader;
+
+    private volatile boolean closed;
 
     private ImageReader(SharedImageReader reader) {
         this.reader = reader;
     }
 

@@ -69,129 +71,133 @@
         return open(imagePath, ByteOrder.nativeOrder());
     }
 
     @Override
     public void close() throws IOException {
-        if (reader == null) {
+        if (closed) {
             throw new IOException("image file already closed");
         }
-
         reader.close(this);
-        reader = null;
+        closed = true;
     }
 
-    // directory management interface
-    public Directory getRootDirectory() throws IOException {
-        if (reader == null) {
+    private void ensureOpen() throws IOException {
+        if (closed) {
             throw new IOException("image file closed");
         }
+    }
+
+    private void requireOpen() {
+        if (closed) {
+            throw new IllegalStateException("image file closed");
+        }
+    }
+
+    // directory management interface
+    public Directory getRootDirectory() throws IOException {
+        ensureOpen();
         return reader.getRootDirectory();
     }
 
+
     public Node findNode(String name) throws IOException {
-        if (reader == null) {
-            throw new IOException("image file closed");
-        }
+        ensureOpen();
         return reader.findNode(name);
     }
 
     public byte[] getResource(Node node) throws IOException {
-        if (reader == null) {
-            throw new IOException("image file closed");
-        }
+        ensureOpen();
         return reader.getResource(node);
     }
 
     public byte[] getResource(Resource rs) throws IOException {
-        if (reader == null) {
-            throw new IOException("image file closed");
-        }
+        ensureOpen();
         return reader.getResource(rs);
     }
 
     public ImageHeader getHeader() {
-        Objects.requireNonNull(reader, "image file closed");
+        requireOpen();
         return reader.getHeader();
     }
 
     public static void releaseByteBuffer(ByteBuffer buffer) {
         BasicImageReader.releaseByteBuffer(buffer);
     }
 
     public String getName() {
-        Objects.requireNonNull(reader, "image file closed");
-        return reader.getName() ;
+        requireOpen();
+        return reader.getName();
     }
 
     public ByteOrder getByteOrder() {
-        Objects.requireNonNull(reader, "image file closed");
+        requireOpen();
         return reader.getByteOrder();
     }
 
     public Path getImagePath() {
-        Objects.requireNonNull(reader, "image file closed");
+        requireOpen();
         return reader.getImagePath();
     }
 
     public ImageStringsReader getStrings() {
-        Objects.requireNonNull(reader, "image file closed");
+        requireOpen();
         return reader.getStrings();
     }
 
     public ImageLocation findLocation(String mn, String rn) {
-        Objects.requireNonNull(reader, "image file closed");
+        requireOpen();
         return reader.findLocation(mn, rn);
     }
 
     public ImageLocation findLocation(String name) {
-        Objects.requireNonNull(reader, "image file closed");
+        requireOpen();
         return reader.findLocation(name);
     }
 
     public String[] getEntryNames() {
-        Objects.requireNonNull(reader, "image file closed");
+        requireOpen();
         return reader.getEntryNames();
     }
 
     public String[] getModuleNames() {
-        Objects.requireNonNull(reader, "image file closed");
+        requireOpen();
         int off = "/modules/".length();
         return reader.findNode("/modules")
                      .getChildren()
                      .stream()
                      .map(Node::getNameString)
                      .map(s -> s.substring(off, s.length()))
                      .toArray(String[]::new);
     }
 
     public long[] getAttributes(int offset) {
-        Objects.requireNonNull(reader, "image file closed");
+        requireOpen();
         return reader.getAttributes(offset);
     }
 
     public String getString(int offset) {
-        Objects.requireNonNull(reader, "image file closed");
+        requireOpen();
         return reader.getString(offset);
     }
 
     public byte[] getResource(String name) {
-        Objects.requireNonNull(reader, "image file closed");
+        requireOpen();
         return reader.getResource(name);
     }
 
     public byte[] getResource(ImageLocation loc) {
-        Objects.requireNonNull(reader, "image file closed");
+        requireOpen();
         return reader.getResource(loc);
     }
 
     public ByteBuffer getResourceBuffer(ImageLocation loc) {
-        Objects.requireNonNull(reader, "image file closed");
+        requireOpen();
         return reader.getResourceBuffer(loc);
     }
 
     public InputStream getResourceStream(ImageLocation loc) {
-        Objects.requireNonNull(reader, "image file closed");
+        requireOpen();
         return reader.getResourceStream(loc);
     }
 
     private final static class SharedImageReader extends BasicImageReader {
         static final int SIZE_OF_OFFSET = Integer.BYTES;
< prev index next >