Merge "RESTRICT AUTOMERGE Close TextClassifier native resources." into pi-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
d14c8a2a72
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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. */
|
||||
|
||||
Reference in New Issue
Block a user