Fixes in close() in BinaryDictionary.

Avoid using 'synchronized' in finalizer as well.

bug: 3340837
Change-Id: I9b28f54e4490ecb844ba33a379f71b625e4246a2
main
Ken Wakasa 2011-01-17 15:13:45 +09:00
parent 67e08bb0fb
commit da50e1e98d
4 changed files with 33 additions and 13 deletions

View File

@ -42,6 +42,7 @@ public class BinaryDictionary extends Dictionary {
private static final int TYPED_LETTER_MULTIPLIER = 2; private static final int TYPED_LETTER_MULTIPLIER = 2;
private static final BinaryDictionary sInstance = new BinaryDictionary();
private int mDicTypeId; private int mDicTypeId;
private int mNativeDict; private int mNativeDict;
private long mDictLength; private long mDictLength;
@ -59,16 +60,24 @@ public class BinaryDictionary extends Dictionary {
} }
} }
private BinaryDictionary() {
}
/** /**
* Create a dictionary from a raw resource file * Initialize a dictionary from a raw resource file
* @param context application context for reading resources * @param context application context for reading resources
* @param resId the resource containing the raw binary dictionary * @param resId the resource containing the raw binary dictionary
* @return initialized instance of BinaryDictionary
*/ */
public BinaryDictionary(Context context, int resId, int dicTypeId) { public static BinaryDictionary initDictionary(Context context, int resId, int dicTypeId) {
synchronized (sInstance) {
sInstance.closeInternal();
if (resId != 0) { if (resId != 0) {
loadDictionary(context, resId); sInstance.loadDictionary(context, resId);
sInstance.mDicTypeId = dicTypeId;
} }
mDicTypeId = dicTypeId; }
return sInstance;
} }
private native int openNative(String sourceDir, long dictOffset, long dictSize, private native int openNative(String sourceDir, long dictOffset, long dictSize,
@ -104,6 +113,8 @@ public class BinaryDictionary extends Dictionary {
@Override @Override
public void getBigrams(final WordComposer codes, final CharSequence previousWord, public void getBigrams(final WordComposer codes, final CharSequence previousWord,
final WordCallback callback, int[] nextLettersFrequencies) { final WordCallback callback, int[] nextLettersFrequencies) {
if (mNativeDict == 0) return;
char[] chars = previousWord.toString().toCharArray(); char[] chars = previousWord.toString().toCharArray();
Arrays.fill(mOutputChars_bigrams, (char) 0); Arrays.fill(mOutputChars_bigrams, (char) 0);
Arrays.fill(mFrequencies_bigrams, 0); Arrays.fill(mFrequencies_bigrams, 0);
@ -135,6 +146,8 @@ public class BinaryDictionary extends Dictionary {
@Override @Override
public void getWords(final WordComposer codes, final WordCallback callback, public void getWords(final WordComposer codes, final WordCallback callback,
int[] nextLettersFrequencies) { int[] nextLettersFrequencies) {
if (mNativeDict == 0) return;
final int codesSize = codes.size(); final int codesSize = codes.size();
// Won't deal with really long words. // Won't deal with really long words.
if (codesSize > MAX_WORD_LENGTH - 1) return; if (codesSize > MAX_WORD_LENGTH - 1) return;
@ -179,6 +192,10 @@ public class BinaryDictionary extends Dictionary {
@Override @Override
public synchronized void close() { public synchronized void close() {
closeInternal();
}
private void closeInternal() {
if (mNativeDict != 0) { if (mNativeDict != 0) {
closeNative(mNativeDict); closeNative(mNativeDict);
mNativeDict = 0; mNativeDict = 0;
@ -188,7 +205,10 @@ public class BinaryDictionary extends Dictionary {
@Override @Override
protected void finalize() throws Throwable { protected void finalize() throws Throwable {
close(); try {
closeInternal();
} finally {
super.finalize(); super.finalize();
} }
}
} }

View File

@ -107,7 +107,7 @@ public class InputLanguageSelection extends PreferenceActivity {
res.updateConfiguration(conf, res.getDisplayMetrics()); res.updateConfiguration(conf, res.getDisplayMetrics());
int mainDicResId = LatinIME.getMainDictionaryResourceId(res); int mainDicResId = LatinIME.getMainDictionaryResourceId(res);
BinaryDictionary bd = new BinaryDictionary(this, mainDicResId, Suggest.DIC_MAIN); BinaryDictionary bd = BinaryDictionary.initDictionary(this, mainDicResId, Suggest.DIC_MAIN);
// Is the dictionary larger than a placeholder? Arbitrarily chose a lower limit of // Is the dictionary larger than a placeholder? Arbitrarily chose a lower limit of
// 4000-5000 words, whereas the LARGE_DICTIONARY is about 20000+ words. // 4000-5000 words, whereas the LARGE_DICTIONARY is about 20000+ words.

View File

@ -103,7 +103,7 @@ public class Suggest implements Dictionary.WordCallback {
private int mCorrectionMode = CORRECTION_BASIC; private int mCorrectionMode = CORRECTION_BASIC;
public Suggest(Context context, int dictionaryResId) { public Suggest(Context context, int dictionaryResId) {
mMainDict = new BinaryDictionary(context, dictionaryResId, DIC_MAIN); mMainDict = BinaryDictionary.initDictionary(context, dictionaryResId, DIC_MAIN);
initPool(); initPool();
} }
@ -127,7 +127,7 @@ public class Suggest implements Dictionary.WordCallback {
} }
public boolean hasMainDictionary() { public boolean hasMainDictionary() {
return mMainDict.getSize() > LARGE_DICTIONARY_THRESHOLD; return mMainDict != null && mMainDict.getSize() > LARGE_DICTIONARY_THRESHOLD;
} }
public int getApproxMaxWordLength() { public int getApproxMaxWordLength() {
@ -276,7 +276,7 @@ public class Suggest implements Dictionary.WordCallback {
mHaveCorrection = true; mHaveCorrection = true;
} }
} }
mMainDict.getWords(wordComposer, this, mNextLettersFrequencies); if (mMainDict != null) mMainDict.getWords(wordComposer, this, mNextLettersFrequencies);
if ((mCorrectionMode == CORRECTION_FULL || mCorrectionMode == CORRECTION_FULL_BIGRAM) if ((mCorrectionMode == CORRECTION_FULL || mCorrectionMode == CORRECTION_FULL_BIGRAM)
&& mSuggestions.size() > 0 && mPriorities.length > 0) { && mSuggestions.size() > 0 && mPriorities.length > 0) {
// TODO: when the normalized score of the first suggestion is nearly equals to // TODO: when the normalized score of the first suggestion is nearly equals to
@ -496,7 +496,7 @@ public class Suggest implements Dictionary.WordCallback {
} }
public boolean isValidWord(final CharSequence word) { public boolean isValidWord(final CharSequence word) {
if (word == null || word.length() == 0) { if (word == null || word.length() == 0 || mMainDict == null) {
return false; return false;
} }
return mMainDict.isValidWord(word) return mMainDict.isValidWord(word)

View File

@ -89,7 +89,7 @@ static jint latinime_BinaryDictionary_open(JNIEnv *env, jobject object,
return 0; return 0;
} }
dictBuf = malloc(sizeof(char) * dictSize); dictBuf = malloc(sizeof(char) * dictSize);
if (dictBuf == NULL) { if (!dictBuf) {
LOGE("DICT: Can't allocate memory region for dictionary. errno=%d", errno); LOGE("DICT: Can't allocate memory region for dictionary. errno=%d", errno);
return 0; return 0;
} }