diff options
author | Doug Zongker <dougz@google.com> | 2014-06-23 12:51:08 -0700 |
---|---|---|
committer | Doug Zongker <dougz@google.com> | 2014-06-23 13:15:43 -0700 |
commit | 77ffe2074affbef2ff8876ae64d20f5923222de7 (patch) | |
tree | bb1dc307c2e50e5df94e485cd50018c5c2ffe663 /common | |
parent | 01e7c02174ef268b6d6daaa5a5bb4f752d55964c (diff) | |
download | android_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.java | 16 |
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()); + } } } } |