Merge "RESTRICT AUTOMERGE Close TextClassifier native resources." into pi-dev

This commit is contained in:
TreeHugger Robot
2019-02-14 16:22:18 +00:00
committed by Android (Google) Code Review
2 changed files with 39 additions and 12 deletions

View File

@@ -64,6 +64,9 @@ import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
//TODO: use java.lang.ref.Cleaner once Android supports Java 9
import sun.misc.Cleaner;
/**
* Default implementation of the {@link TextClassifier} interface.
*
@@ -92,6 +95,8 @@ public final class TextClassifierImpl implements TextClassifier {
private ModelFile mModel;
@GuardedBy("mLock") // Do not access outside this lock.
private TextClassifierImplNative mNative;
@GuardedBy("mLock")
private Cleaner mNativeCleaner;
private final Object mLoggerLock = new Object();
@GuardedBy("mLoggerLock") // Do not access outside this lock.
@@ -304,12 +309,12 @@ public final class TextClassifierImpl implements TextClassifier {
if (bestModel == null) {
throw new FileNotFoundException("No model for " + localeList.toLanguageTags());
}
if (mNative == null || !Objects.equals(mModel, bestModel)) {
if (mNative == null || mNative.isClosed() || !Objects.equals(mModel, bestModel)) {
Log.d(DEFAULT_LOG_TAG, "Loading " + bestModel);
destroyNativeIfExistsLocked();
final ParcelFileDescriptor fd = ParcelFileDescriptor.open(
new File(bestModel.getPath()), ParcelFileDescriptor.MODE_READ_ONLY);
mNative = new TextClassifierImplNative(fd.getFd());
mNativeCleaner = Cleaner.create(this, new NativeCloser(mNative));
closeAndLogError(fd);
mModel = bestModel;
}
@@ -324,14 +329,6 @@ public final class TextClassifierImpl implements TextClassifier {
}
}
@GuardedBy("mLock") // Do not call outside this lock.
private void destroyNativeIfExistsLocked() {
if (mNative != null) {
mNative.close();
mNative = null;
}
}
private static String concatenateLocales(@Nullable LocaleList locales) {
return (locales == null) ? "" : locales.toLanguageTags();
}
@@ -822,4 +819,21 @@ public final class TextClassifierImpl implements TextClassifier {
parsedTime.hashCode());
}
}
/**
* Code to close a TextClassifierImplNative. Must not reference the TextClassifierImpl.
*/
private static final class NativeCloser implements Runnable {
private final TextClassifierImplNative mNative;
NativeCloser(TextClassifierImplNative nativeImpl) {
mNative = Preconditions.checkNotNull(nativeImpl);
}
@Override
public void run() {
mNative.close();
}
}
}

View File

@@ -28,7 +28,8 @@ final class TextClassifierImplNative {
System.loadLibrary("textclassifier");
}
private final long mModelPtr;
private final Object mCloseLock = new Object();
private long mModelPtr;
/**
* Creates a new instance of TextClassifierImplNative, using the provided model image, given as
@@ -102,7 +103,19 @@ final class TextClassifierImplNative {
/** Frees up the allocated memory. */
public void close() {
nativeClose(mModelPtr);
synchronized (mCloseLock) {
if (!isClosed()) {
nativeClose(mModelPtr);
mModelPtr = 0;
}
}
}
/**
* Returns true if this object is closed, returns false otherwise.
*/
public boolean isClosed() {
return mModelPtr == 0L;
}
/** Returns a comma separated list of locales supported by the model as BCP 47 tags. */