8156602: javac crashes again on Windows 32-bit with ClosedChannelException
Reviewed-by: alanb
This commit is contained in:
parent
65a33061ce
commit
3648a0f15f
@ -27,6 +27,8 @@ package jdk.internal.jimage;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.IntBuffer;
|
||||
@ -98,8 +100,34 @@ public class BasicImageReader implements AutoCloseable {
|
||||
}
|
||||
|
||||
// Open the file only if no memory map yet or is 32 bit jvm
|
||||
channel = map != null && MAP_ALL ? null :
|
||||
FileChannel.open(imagePath, StandardOpenOption.READ);
|
||||
if (map != null && MAP_ALL) {
|
||||
channel = null;
|
||||
} else {
|
||||
channel = FileChannel.open(imagePath, StandardOpenOption.READ);
|
||||
// No lambdas during bootstrap
|
||||
AccessController.doPrivileged(new PrivilegedAction<Void>() {
|
||||
@Override
|
||||
public Void run() {
|
||||
if (BasicImageReader.class.getClassLoader() == null) {
|
||||
try {
|
||||
Class<?> fileChannelImpl =
|
||||
Class.forName("sun.nio.ch.FileChannelImpl");
|
||||
Method setUninterruptible =
|
||||
fileChannelImpl.getMethod("setUninterruptible");
|
||||
setUninterruptible.invoke(channel);
|
||||
} catch (ClassNotFoundException |
|
||||
NoSuchMethodException |
|
||||
IllegalAccessException |
|
||||
InvocationTargetException ex) {
|
||||
// fall thru - will only happen on JDK-8 systems where this code
|
||||
// is only used by tools using jrt-fs (non-critical.)
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// If no memory map yet and 64 bit jvm then memory map entire file
|
||||
if (MAP_ALL && map == null) {
|
||||
|
@ -40,7 +40,6 @@ import java.nio.channels.OverlappingFileLockException;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.nio.channels.SelectableChannel;
|
||||
import java.nio.channels.WritableByteChannel;
|
||||
import java.security.AccessController;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@ -83,6 +82,9 @@ public class FileChannelImpl
|
||||
// Lock for operations involving position and size
|
||||
private final Object positionLock = new Object();
|
||||
|
||||
// Positional-read is not interruptible
|
||||
private volatile boolean uninterruptible;
|
||||
|
||||
private FileChannelImpl(FileDescriptor fd, String path, boolean readable,
|
||||
boolean writable, Object parent)
|
||||
{
|
||||
@ -108,6 +110,10 @@ public class FileChannelImpl
|
||||
throw new ClosedChannelException();
|
||||
}
|
||||
|
||||
public void setUninterruptible() {
|
||||
uninterruptible = true;
|
||||
}
|
||||
|
||||
// -- Standard channel operations --
|
||||
|
||||
protected void implCloseChannel() throws IOException {
|
||||
@ -733,8 +739,10 @@ public class FileChannelImpl
|
||||
assert !nd.needsPositionLock() || Thread.holdsLock(positionLock);
|
||||
int n = 0;
|
||||
int ti = -1;
|
||||
|
||||
boolean interruptible = !uninterruptible;
|
||||
try {
|
||||
begin();
|
||||
if (interruptible) begin();
|
||||
ti = threads.add();
|
||||
if (!isOpen())
|
||||
return -1;
|
||||
@ -744,7 +752,7 @@ public class FileChannelImpl
|
||||
return IOStatus.normalize(n);
|
||||
} finally {
|
||||
threads.remove(ti);
|
||||
end(n > 0);
|
||||
if (interruptible) end(n > 0);
|
||||
assert IOStatus.check(n);
|
||||
}
|
||||
}
|
||||
|
@ -76,6 +76,7 @@ jdk_lang = \
|
||||
jdk/lambda \
|
||||
jdk/internal/misc \
|
||||
jdk/internal/ref \
|
||||
jdk/internal/jimage \
|
||||
jdk/modules \
|
||||
vm
|
||||
|
||||
@ -352,7 +353,7 @@ jdk_desktop = \
|
||||
# SwingSet3 tests.
|
||||
jdk_client_sanity = \
|
||||
sanity/client/SwingSet
|
||||
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# Serviceability sanity groups
|
||||
|
95
jdk/test/jdk/internal/jimage/JImageOpenTest.java
Normal file
95
jdk/test/jdk/internal/jimage/JImageOpenTest.java
Normal file
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.lang.reflect.Layer;
|
||||
import java.net.URI;
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/*
|
||||
* jimage shared open testing.
|
||||
* @test
|
||||
* @summary Test to see if thread interrupt handling interferes with other threads.
|
||||
* @build JImageOpenTest.java
|
||||
* @run main/othervm -Djdk.image.map.all=false JImageOpenTest
|
||||
*/
|
||||
public class JImageOpenTest {
|
||||
private static final int NTHREADS = 10;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
final FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/"));
|
||||
final Path root = fs.getPath("/modules");
|
||||
|
||||
final List<String> names = Files.walk(root)
|
||||
.filter(p -> p.getNameCount() > 2)
|
||||
.filter(p -> Layer.boot().findModule(p.getName(1).toString()).isPresent())
|
||||
.map(p -> p.subpath(2, p.getNameCount()))
|
||||
.map(p -> p.toString())
|
||||
.filter(s -> s.endsWith(".class") && !s.endsWith("module-info.class"))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
Runnable r = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
names.forEach(name -> {
|
||||
String cn = name.substring(0, name.length() - 6).replace('/', '.');
|
||||
try {
|
||||
Class.forName(cn, false, ClassLoader.getSystemClassLoader());
|
||||
} catch (Exception ex) {
|
||||
System.err.println(Thread.currentThread() + " " + ex.getClass());
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
Thread[] threads = new Thread[NTHREADS];
|
||||
|
||||
for (int i = 0; i < NTHREADS; i++) {
|
||||
Thread thread = new Thread(r);
|
||||
threads[i] = thread;
|
||||
thread.start();
|
||||
}
|
||||
|
||||
Thread.sleep(1);
|
||||
|
||||
for (int i = 0; i < NTHREADS; i++) {
|
||||
Thread thread = threads[i];
|
||||
|
||||
if (thread.isAlive()) {
|
||||
thread.interrupt();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < NTHREADS; i++) {
|
||||
Thread thread = threads[i];
|
||||
thread.join();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user