diff options
author | Joachim Sauer <jsauer@google.com> | 2016-08-22 11:23:56 +0100 |
---|---|---|
committer | Joachim Sauer <jsauer@google.com> | 2016-08-22 15:20:15 +0100 |
commit | fe2dcd4b7b18c3e0c10fb746aea958dc4ee6dac9 (patch) | |
tree | c1ed46a877804a68b3da5823125937ab93f1f7bb /android_icu4j | |
parent | 35a16e21d16dd42c7ff7cd5a4e0976206522897c (diff) | |
download | icu-fe2dcd4b7b18c3e0c10fb746aea958dc4ee6dac9.tar.gz |
Fix race condition in ICU TimeZone.getDefault()
TimeZone.getDefault() had a race condition where it could fail
with a NullPointerException if called concurrently with
clearCachedDefault().
This fixes the race condition by always copying the defaultZone value
into a local variable and returning that, to ensure that concurrent sets
to defaultZone don't lead to a NullPointerException on the
cloneAsThawed() call.
Bug: 30979219
Test: vogar libcore/luni/src/test/java/libcore/java/util/TimeZoneTest.java
(cherry picked from commit b6127dc5375a9359f67e87d9d73dd2b4cc268942)
Change-Id: Ic3659b7671301f66d10fcf1bb5697a9020ebf91e
Diffstat (limited to 'android_icu4j')
-rw-r--r-- | android_icu4j/src/main/java/android/icu/util/TimeZone.java | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/android_icu4j/src/main/java/android/icu/util/TimeZone.java b/android_icu4j/src/main/java/android/icu/util/TimeZone.java index 7b64afeb2..828ebc6ac 100644 --- a/android_icu4j/src/main/java/android/icu/util/TimeZone.java +++ b/android_icu4j/src/main/java/android/icu/util/TimeZone.java @@ -844,7 +844,10 @@ abstract public class TimeZone implements Serializable, Cloneable, Freezable<Tim * @return a default <code>TimeZone</code>. */ public static TimeZone getDefault() { - if (defaultZone == null) { + // Android patch (http://b/30979219) start. + // Avoid race condition by copying defaultZone to a local variable. + TimeZone result = defaultZone; + if (result == null) { // Android patch (http://b/30937209) start. // Avoid a deadlock by always acquiring monitors in order (1) java.util.TimeZone.class // then (2) icu.util.TimeZone.class and not (2) then (1). @@ -854,19 +857,22 @@ abstract public class TimeZone implements Serializable, Cloneable, Freezable<Tim // icu.util.TimeZone.clearCachedDefault() so always acquires them in order (1) then (2). synchronized (java.util.TimeZone.class) { synchronized (TimeZone.class) { - if (defaultZone == null) { + result = defaultZone; + if (result == null) { if (TZ_IMPL == TIMEZONE_JDK) { - defaultZone = new JavaTimeZone(); + result = new JavaTimeZone(); } else { java.util.TimeZone temp = java.util.TimeZone.getDefault(); - defaultZone = getFrozenTimeZone(temp.getID()); + result = getFrozenTimeZone(temp.getID()); } + defaultZone = result; } } } // Android patch (http://b/30937209) end. } - return defaultZone.cloneAsThawed(); + return result.cloneAsThawed(); + // Android patch (http://b/30979219) end. } // Android patch (http://b/28949992) start. |