summaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorDoug Zongker <dougz@google.com>2014-06-23 12:51:08 -0700
committerDoug Zongker <dougz@google.com>2014-06-23 13:15:43 -0700
commit77ffe2074affbef2ff8876ae64d20f5923222de7 (patch)
treebb1dc307c2e50e5df94e485cd50018c5c2ffe663 /common
parent01e7c02174ef268b6d6daaa5a5bb4f752d55964c (diff)
downloadandroid_frameworks_ex-77ffe2074affbef2ff8876ae64d20f5923222de7.tar.gz
android_frameworks_ex-77ffe2074affbef2ff8876ae64d20f5923222de7.tar.bz2
android_frameworks_ex-77ffe2074affbef2ff8876ae64d20f5923222de7.zip
fix race condition in OperationScheduler
OperationScheduler's toString() method got the set of keys from a SharedPreferences, and then did individual lookups of those keys assuming they would all succeed, but the shared prefs object can be mutated by a another thread while that is going on. Fix to take a snapshot with getAll() and then iterate over the snapshot. Bug: 15744821 Change-Id: I6a901ec7f4e632e149db3bf6c226f935bc152402
Diffstat (limited to 'common')
-rw-r--r--common/java/com/android/common/OperationScheduler.java16
1 files changed, 12 insertions, 4 deletions
diff --git a/common/java/com/android/common/OperationScheduler.java b/common/java/com/android/common/OperationScheduler.java
index 81371ef..22dfe41 100644
--- a/common/java/com/android/common/OperationScheduler.java
+++ b/common/java/com/android/common/OperationScheduler.java
@@ -20,7 +20,8 @@ import android.content.SharedPreferences;
import android.net.http.AndroidHttpClient;
import android.text.format.Time;
-import java.util.TreeSet;
+import java.util.Map;
+import java.util.TreeMap;
/**
* Tracks the success/failure history of a particular network operation in
@@ -355,16 +356,23 @@ public class OperationScheduler {
*/
public String toString() {
StringBuilder out = new StringBuilder("[OperationScheduler:");
- for (String key : new TreeSet<String>(mStorage.getAll().keySet())) { // Sort keys
+ TreeMap<String, Object> copy = new TreeMap<String, Object>(mStorage.getAll()); // Sort keys
+ for (Map.Entry<String, Object> e : copy.entrySet()) {
+ String key = e.getKey();
if (key.startsWith(PREFIX)) {
if (key.endsWith("TimeMillis")) {
Time time = new Time();
- time.set(mStorage.getLong(key, 0));
+ time.set((Long) e.getValue());
out.append(" ").append(key.substring(PREFIX.length(), key.length() - 10));
out.append("=").append(time.format("%Y-%m-%d/%H:%M:%S"));
} else {
out.append(" ").append(key.substring(PREFIX.length()));
- out.append("=").append(mStorage.getAll().get(key).toString());
+ Object v = e.getValue();
+ if (v == null) {
+ out.append("=(null)");
+ } else {
+ out.append("=").append(v.toString());
+ }
}
}
}