Merge "Add shutdown and isTerminated to PrioritizedSerialExecutor."

main
Satoshi Kataoka 2013-09-13 08:51:43 +00:00 committed by Android (Google) Code Review
commit ffebc9cfa7
3 changed files with 55 additions and 9 deletions

View File

@ -617,4 +617,14 @@ abstract public class ExpandableBinaryDictionary extends Dictionary {
}); });
return holder.get(false, TIMEOUT_FOR_READ_OPS_IN_MILLISECONDS); return holder.get(false, TIMEOUT_FOR_READ_OPS_IN_MILLISECONDS);
} }
@UsedForTesting
public void shutdownExecutorForTests() {
getExecutor(mFilename).shutdown();
}
@UsedForTesting
public boolean isTerminatedForTests() {
return getExecutor(mFilename).isTerminated();
}
} }

View File

@ -31,6 +31,7 @@ public class PrioritizedSerialExecutor {
private static final int TASK_QUEUE_CAPACITY = 1000; private static final int TASK_QUEUE_CAPACITY = 1000;
private final Queue<Runnable> mTasks; private final Queue<Runnable> mTasks;
private final Queue<Runnable> mPrioritizedTasks; private final Queue<Runnable> mPrioritizedTasks;
private boolean mIsShutdown;
// The task which is running now. // The task which is running now.
private Runnable mActive; private Runnable mActive;
@ -38,6 +39,7 @@ public class PrioritizedSerialExecutor {
public PrioritizedSerialExecutor() { public PrioritizedSerialExecutor() {
mTasks = new ArrayDeque<Runnable>(TASK_QUEUE_CAPACITY); mTasks = new ArrayDeque<Runnable>(TASK_QUEUE_CAPACITY);
mPrioritizedTasks = new ArrayDeque<Runnable>(TASK_QUEUE_CAPACITY); mPrioritizedTasks = new ArrayDeque<Runnable>(TASK_QUEUE_CAPACITY);
mIsShutdown = false;
} }
/** /**
@ -56,9 +58,11 @@ public class PrioritizedSerialExecutor {
*/ */
public void execute(final Runnable r) { public void execute(final Runnable r) {
synchronized(mLock) { synchronized(mLock) {
mTasks.offer(r); if (!mIsShutdown) {
if (mActive == null) { mTasks.offer(r);
scheduleNext(); if (mActive == null) {
scheduleNext();
}
} }
} }
} }
@ -69,9 +73,11 @@ public class PrioritizedSerialExecutor {
*/ */
public void executePrioritized(final Runnable r) { public void executePrioritized(final Runnable r) {
synchronized(mLock) { synchronized(mLock) {
mPrioritizedTasks.offer(r); if (!mIsShutdown) {
if (mActive == null) { mPrioritizedTasks.offer(r);
scheduleNext(); if (mActive == null) {
scheduleNext();
}
} }
} }
} }
@ -123,4 +129,19 @@ public class PrioritizedSerialExecutor {
execute(newTask); execute(newTask);
} }
} }
public void shutdown() {
synchronized(mLock) {
mIsShutdown = true;
}
}
public boolean isTerminated() {
synchronized(mLock) {
if (!mIsShutdown) {
return false;
}
return mPrioritizedTasks.isEmpty() && mTasks.isEmpty() && mActive == null;
}
}
} }

View File

@ -46,6 +46,7 @@ public class UserHistoryDictionaryTests extends AndroidTestCase {
}; };
private static final int MIN_USER_HISTORY_DICTIONARY_FILE_SIZE = 1000; private static final int MIN_USER_HISTORY_DICTIONARY_FILE_SIZE = 1000;
private static final int WAIT_TERMINATING_IN_MILLISECONDS = 100;
@Override @Override
public void setUp() { public void setUp() {
@ -122,8 +123,14 @@ public class UserHistoryDictionaryTests extends AndroidTestCase {
true /* checksContents */); true /* checksContents */);
} finally { } finally {
try { try {
final UserHistoryPredictionDictionary dict =
PersonalizationHelper.getUserHistoryPredictionDictionary(getContext(),
testFilenameSuffix, mPrefs);
Log.d(TAG, "waiting for writing ..."); Log.d(TAG, "waiting for writing ...");
Thread.sleep(TimeUnit.MILLISECONDS.convert(5L, TimeUnit.SECONDS)); dict.shutdownExecutorForTests();
while (!dict.isTerminatedForTests()) {
Thread.sleep(WAIT_TERMINATING_IN_MILLISECONDS);
}
} catch (InterruptedException e) { } catch (InterruptedException e) {
Log.d(TAG, "InterruptedException: " + e); Log.d(TAG, "InterruptedException: " + e);
} }
@ -146,11 +153,11 @@ public class UserHistoryDictionaryTests extends AndroidTestCase {
final int numberOfWordsInsertedForEachLanguageSwitch = 100; final int numberOfWordsInsertedForEachLanguageSwitch = 100;
final File dictFiles[] = new File[numberOfLanguages]; final File dictFiles[] = new File[numberOfLanguages];
final String testFilenameSuffixes[] = new String[numberOfLanguages];
try { try {
final Random random = new Random(123456); final Random random = new Random(123456);
// Create filename suffixes for this test. // Create filename suffixes for this test.
String testFilenameSuffixes[] = new String[numberOfLanguages];
for (int i = 0; i < numberOfLanguages; i++) { for (int i = 0; i < numberOfLanguages; i++) {
testFilenameSuffixes[i] = "testSwitchingLanguages" + i; testFilenameSuffixes[i] = "testSwitchingLanguages" + i;
final String fileName = UserHistoryPredictionDictionary.NAME + "." + final String fileName = UserHistoryPredictionDictionary.NAME + "." +
@ -174,7 +181,15 @@ public class UserHistoryDictionaryTests extends AndroidTestCase {
} finally { } finally {
try { try {
Log.d(TAG, "waiting for writing ..."); Log.d(TAG, "waiting for writing ...");
Thread.sleep(TimeUnit.MILLISECONDS.convert(5L, TimeUnit.SECONDS)); for (int i = 0; i < numberOfLanguages; i++) {
final UserHistoryPredictionDictionary dict =
PersonalizationHelper.getUserHistoryPredictionDictionary(getContext(),
testFilenameSuffixes[i], mPrefs);
dict.shutdownExecutorForTests();
while (!dict.isTerminatedForTests()) {
Thread.sleep(WAIT_TERMINATING_IN_MILLISECONDS);
}
}
} catch (InterruptedException e) { } catch (InterruptedException e) {
Log.d(TAG, "InterruptedException: " + e); Log.d(TAG, "InterruptedException: " + e);
} }