Fix FileInputStream Java10+ compatibility
This commit is contained in:
parent
49e142f8cd
commit
2dee789931
|
@ -1,107 +0,0 @@
|
|||
/*
|
||||
* This file is part of libbluray
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package java.io;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public final class FileDescriptor {
|
||||
|
||||
/* for files used by JVM */
|
||||
private int fd;
|
||||
private long handle;
|
||||
|
||||
private int useCount;
|
||||
|
||||
public FileDescriptor() {
|
||||
fd = -1;
|
||||
handle = -1;
|
||||
useCount = 0;
|
||||
}
|
||||
|
||||
private FileDescriptor(int fd) {
|
||||
this();
|
||||
this.fd = fd;
|
||||
}
|
||||
|
||||
public static final FileDescriptor in = new FileDescriptor(0);
|
||||
public static final FileDescriptor out = new FileDescriptor(1);
|
||||
public static final FileDescriptor err = new FileDescriptor(2);
|
||||
|
||||
public boolean valid() {
|
||||
return (fd != -1) || (handle != -1);
|
||||
}
|
||||
|
||||
public native void sync() throws SyncFailedException;
|
||||
|
||||
private static native void initIDs();
|
||||
|
||||
static {
|
||||
initIDs();
|
||||
}
|
||||
|
||||
int incrementAndGetUseCount() {
|
||||
synchronized (this) {
|
||||
useCount = useCount + 1;
|
||||
return useCount;
|
||||
}
|
||||
}
|
||||
|
||||
int decrementAndGetUseCount() {
|
||||
synchronized (this) {
|
||||
useCount = useCount - 1;
|
||||
return useCount;
|
||||
}
|
||||
}
|
||||
|
||||
/* Java 8 */
|
||||
|
||||
private List parents = null;
|
||||
private boolean closed = false;
|
||||
|
||||
synchronized void attach(Closeable c) {
|
||||
if (parents == null) {
|
||||
parents = new ArrayList();
|
||||
}
|
||||
parents.add(c);
|
||||
}
|
||||
|
||||
synchronized void closeAll(Closeable releaser) throws IOException {
|
||||
if (!closed) {
|
||||
IOException ex = null;
|
||||
closed = true;
|
||||
|
||||
for (Iterator it = parents.iterator(); it.hasNext(); ) {
|
||||
Closeable c = (Closeable)it.next();
|
||||
try {
|
||||
c.close();
|
||||
} catch (IOException ioe) {
|
||||
if (ex != null)
|
||||
ex = ioe;
|
||||
}
|
||||
}
|
||||
|
||||
releaser.close();
|
||||
if (ex != null) {
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
package java.io;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
import org.videolan.BDJLoader;
|
||||
import org.videolan.BDJXletContext;
|
||||
|
@ -46,7 +47,7 @@ public class FileInputStream extends InputStream
|
|||
}
|
||||
|
||||
fd = new FileDescriptor();
|
||||
fd.incrementAndGetUseCount();
|
||||
fdAttach();
|
||||
|
||||
if (file.isAbsolute()) {
|
||||
String cachedName = BDJLoader.getCachedFile(name);
|
||||
|
@ -82,9 +83,9 @@ public class FileInputStream extends InputStream
|
|||
if (security != null) {
|
||||
security.checkRead(fdObj);
|
||||
}
|
||||
fdObj.incrementAndGetUseCount();
|
||||
fd = fdObj;
|
||||
available = 1024;
|
||||
fdAttach();
|
||||
}
|
||||
|
||||
/* open()/open0() wrapper to select correct native method at runtime */
|
||||
|
@ -98,6 +99,7 @@ public class FileInputStream extends InputStream
|
|||
}
|
||||
|
||||
private native int readBytes(byte b[], int off, int len) throws IOException;
|
||||
/* OpenJDK < 10 */
|
||||
private native int close0();
|
||||
/* OpenJDK 6, OpenJDK 7, PhoneME, ... */
|
||||
private native void open(String name) throws FileNotFoundException;
|
||||
|
@ -146,7 +148,7 @@ public class FileInputStream extends InputStream
|
|||
close(true);
|
||||
}
|
||||
|
||||
public void close(boolean force) throws IOException {
|
||||
private void close(boolean force) throws IOException {
|
||||
synchronized (closeLock) {
|
||||
if (closed) {
|
||||
return;
|
||||
|
@ -156,14 +158,7 @@ public class FileInputStream extends InputStream
|
|||
|
||||
available = 0;
|
||||
|
||||
if (fd != null) {
|
||||
int n = fd.decrementAndGetUseCount();
|
||||
if (n > 0 && !force) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
close0();
|
||||
fdClose(force);
|
||||
}
|
||||
|
||||
public final FileDescriptor getFD() throws IOException {
|
||||
|
@ -199,4 +194,111 @@ public class FileInputStream extends InputStream
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* compat layer
|
||||
*/
|
||||
|
||||
private boolean useFdCount = false;
|
||||
|
||||
private void fdAttach() {
|
||||
|
||||
/*
|
||||
* Reflection fails at very early stage in JVM bootstrap.
|
||||
* -> hide all errors in this function.
|
||||
*/
|
||||
try {
|
||||
try {
|
||||
fd.getClass().getDeclaredMethod("attach", new Class[] { Closeable.class })
|
||||
.invoke(fd, new Object[] { (Object)this });
|
||||
return;
|
||||
} catch (NoSuchMethodException e) {
|
||||
/* older RT libs */
|
||||
}
|
||||
|
||||
try {
|
||||
fd.getClass().getDeclaredMethod("incrementAndGetUseCount", new Class[0]).invoke((Object)fd, new Object[0]);
|
||||
useFdCount = true;
|
||||
return;
|
||||
} catch (NoSuchMethodException e) {
|
||||
getLogger().error("internal error in FileDescriptor usage");
|
||||
}
|
||||
|
||||
} catch (Throwable t) {
|
||||
if (logger != null)
|
||||
logger.error("" + t);
|
||||
}
|
||||
}
|
||||
|
||||
private void closeImpl() throws IOException {
|
||||
|
||||
/* OpenJDK 10+ */
|
||||
try {
|
||||
fd.getClass().getDeclaredMethod("close", new Class[0])
|
||||
.invoke(fd, new Object[0]);
|
||||
return;
|
||||
} catch (InvocationTargetException ite) {
|
||||
Throwable t = ite.getTargetException();
|
||||
getLogger().error("" + t);
|
||||
if (t instanceof IOException) {
|
||||
throw (IOException)t;
|
||||
}
|
||||
throw new IOException();
|
||||
} catch (IllegalAccessException iae) {
|
||||
getLogger().error("internal error in FileDescriptor usage: " + iae);
|
||||
return;
|
||||
} catch (NoSuchMethodException no_jdk10) {
|
||||
/* JDK < 10 */
|
||||
}
|
||||
|
||||
/* JDK < 10 */
|
||||
try {
|
||||
close0();
|
||||
} catch (UnsatisfiedLinkError no_close0) {
|
||||
getLogger().error("internal error in FileDescriptor usage: " + no_close0);
|
||||
}
|
||||
}
|
||||
|
||||
private void fdClose(boolean force) throws IOException {
|
||||
|
||||
try {
|
||||
|
||||
if (useFdCount) {
|
||||
try {
|
||||
Integer i = (Integer) fd.getClass().getDeclaredMethod("decrementAndGetUseCount", new Class[0]).invoke((Object)fd, new Object[0]);
|
||||
if (i.intValue() > 0 && !force) {
|
||||
return;
|
||||
}
|
||||
closeImpl();
|
||||
} catch (NoSuchMethodException no_method) {
|
||||
getLogger().error("internal error in FileDescriptor usage: " + no_method);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
fd.getClass().getDeclaredMethod("closeAll", new Class[] { Closeable.class })
|
||||
.invoke(fd, new Object[] { (Object)
|
||||
new Closeable() {
|
||||
public void close() throws IOException {
|
||||
closeImpl();
|
||||
}
|
||||
}});
|
||||
return;
|
||||
} catch (NoSuchMethodException no_closeAll) {
|
||||
getLogger().error("internal error in FileDescriptor usage: " + no_closeAll);
|
||||
}
|
||||
|
||||
} catch (IllegalAccessException iae) {
|
||||
getLogger().error("internal error in FileDescriptor usage: " + iae);
|
||||
return;
|
||||
} catch (InvocationTargetException ite) {
|
||||
Throwable t = ite.getTargetException();
|
||||
getLogger().error("" + t);
|
||||
if (t instanceof IOException) {
|
||||
throw (IOException)t;
|
||||
}
|
||||
throw new IOException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue