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