From da50e1e98dadc3733c615dfb8d87fe8b4688c782 Mon Sep 17 00:00:00 2001 From: Ken Wakasa Date: Mon, 17 Jan 2011 15:13:45 +0900 Subject: [PATCH] Fixes in close() in BinaryDictionary. Avoid using 'synchronized' in finalizer as well. bug: 3340837 Change-Id: I9b28f54e4490ecb844ba33a379f71b625e4246a2 --- .../inputmethod/latin/BinaryDictionary.java | 34 +++++++++++++++---- .../latin/InputLanguageSelection.java | 2 +- .../android/inputmethod/latin/Suggest.java | 8 ++--- ...oid_inputmethod_latin_BinaryDictionary.cpp | 2 +- 4 files changed, 33 insertions(+), 13 deletions(-) diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java index f7e67673a..813f7d32f 100644 --- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java @@ -42,6 +42,7 @@ public class BinaryDictionary extends Dictionary { private static final int TYPED_LETTER_MULTIPLIER = 2; + private static final BinaryDictionary sInstance = new BinaryDictionary(); private int mDicTypeId; private int mNativeDict; 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 resId the resource containing the raw binary dictionary + * @return initialized instance of BinaryDictionary */ - public BinaryDictionary(Context context, int resId, int dicTypeId) { - if (resId != 0) { - loadDictionary(context, resId); + public static BinaryDictionary initDictionary(Context context, int resId, int dicTypeId) { + synchronized (sInstance) { + sInstance.closeInternal(); + if (resId != 0) { + sInstance.loadDictionary(context, resId); + sInstance.mDicTypeId = dicTypeId; + } } - mDicTypeId = dicTypeId; + return sInstance; } private native int openNative(String sourceDir, long dictOffset, long dictSize, @@ -104,6 +113,8 @@ public class BinaryDictionary extends Dictionary { @Override public void getBigrams(final WordComposer codes, final CharSequence previousWord, final WordCallback callback, int[] nextLettersFrequencies) { + if (mNativeDict == 0) return; + char[] chars = previousWord.toString().toCharArray(); Arrays.fill(mOutputChars_bigrams, (char) 0); Arrays.fill(mFrequencies_bigrams, 0); @@ -135,6 +146,8 @@ public class BinaryDictionary extends Dictionary { @Override public void getWords(final WordComposer codes, final WordCallback callback, int[] nextLettersFrequencies) { + if (mNativeDict == 0) return; + final int codesSize = codes.size(); // Won't deal with really long words. if (codesSize > MAX_WORD_LENGTH - 1) return; @@ -179,6 +192,10 @@ public class BinaryDictionary extends Dictionary { @Override public synchronized void close() { + closeInternal(); + } + + private void closeInternal() { if (mNativeDict != 0) { closeNative(mNativeDict); mNativeDict = 0; @@ -188,7 +205,10 @@ public class BinaryDictionary extends Dictionary { @Override protected void finalize() throws Throwable { - close(); - super.finalize(); + try { + closeInternal(); + } finally { + super.finalize(); + } } } diff --git a/java/src/com/android/inputmethod/latin/InputLanguageSelection.java b/java/src/com/android/inputmethod/latin/InputLanguageSelection.java index faee38eda..a9f2c2c22 100644 --- a/java/src/com/android/inputmethod/latin/InputLanguageSelection.java +++ b/java/src/com/android/inputmethod/latin/InputLanguageSelection.java @@ -107,7 +107,7 @@ public class InputLanguageSelection extends PreferenceActivity { res.updateConfiguration(conf, res.getDisplayMetrics()); 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 // 4000-5000 words, whereas the LARGE_DICTIONARY is about 20000+ words. diff --git a/java/src/com/android/inputmethod/latin/Suggest.java b/java/src/com/android/inputmethod/latin/Suggest.java index 9ea9c2f3e..a8454b23e 100644 --- a/java/src/com/android/inputmethod/latin/Suggest.java +++ b/java/src/com/android/inputmethod/latin/Suggest.java @@ -103,7 +103,7 @@ public class Suggest implements Dictionary.WordCallback { private int mCorrectionMode = CORRECTION_BASIC; public Suggest(Context context, int dictionaryResId) { - mMainDict = new BinaryDictionary(context, dictionaryResId, DIC_MAIN); + mMainDict = BinaryDictionary.initDictionary(context, dictionaryResId, DIC_MAIN); initPool(); } @@ -127,7 +127,7 @@ public class Suggest implements Dictionary.WordCallback { } public boolean hasMainDictionary() { - return mMainDict.getSize() > LARGE_DICTIONARY_THRESHOLD; + return mMainDict != null && mMainDict.getSize() > LARGE_DICTIONARY_THRESHOLD; } public int getApproxMaxWordLength() { @@ -276,7 +276,7 @@ public class Suggest implements Dictionary.WordCallback { mHaveCorrection = true; } } - mMainDict.getWords(wordComposer, this, mNextLettersFrequencies); + if (mMainDict != null) mMainDict.getWords(wordComposer, this, mNextLettersFrequencies); if ((mCorrectionMode == CORRECTION_FULL || mCorrectionMode == CORRECTION_FULL_BIGRAM) && mSuggestions.size() > 0 && mPriorities.length > 0) { // 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) { - if (word == null || word.length() == 0) { + if (word == null || word.length() == 0 || mMainDict == null) { return false; } return mMainDict.isValidWord(word) diff --git a/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp b/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp index 6e4e97138..25580f4b1 100644 --- a/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp +++ b/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp @@ -89,7 +89,7 @@ static jint latinime_BinaryDictionary_open(JNIEnv *env, jobject object, return 0; } dictBuf = malloc(sizeof(char) * dictSize); - if (dictBuf == NULL) { + if (!dictBuf) { LOGE("DICT: Can't allocate memory region for dictionary. errno=%d", errno); return 0; }