From 9a9d502d682439ba20859073146924bf826f3a37 Mon Sep 17 00:00:00 2001 From: Marcono1234 Date: Sat, 25 Sep 2021 00:30:17 +0200 Subject: [PATCH 1/2] Improve TreeTypeAdapter thread-safety Gson claims to be thread-safe so TreeTypeAdapter.delegate() might be called by multiple threads. To guarantee that each thread sees a fully constructed `delegate`, the field has to be `volatile`. --- .../java/com/google/gson/internal/bind/TreeTypeAdapter.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gson/src/main/java/com/google/gson/internal/bind/TreeTypeAdapter.java b/gson/src/main/java/com/google/gson/internal/bind/TreeTypeAdapter.java index a5c6c5dcda..bc26ea8898 100644 --- a/gson/src/main/java/com/google/gson/internal/bind/TreeTypeAdapter.java +++ b/gson/src/main/java/com/google/gson/internal/bind/TreeTypeAdapter.java @@ -47,7 +47,7 @@ public final class TreeTypeAdapter extends TypeAdapter { private final GsonContextImpl context = new GsonContextImpl(); /** The delegate is lazily created because it may not be needed, and creating it may fail. */ - private TypeAdapter delegate; + private volatile TypeAdapter delegate; public TreeTypeAdapter(JsonSerializer serializer, JsonDeserializer deserializer, Gson gson, TypeToken typeToken, TypeAdapterFactory skipPast) { @@ -83,6 +83,7 @@ public TreeTypeAdapter(JsonSerializer serializer, JsonDeserializer deseria } private TypeAdapter delegate() { + // Allows racy initialization of `delegate` by multiple threads TypeAdapter d = delegate; return d != null ? d From c316f7d7e223509575d915a3f316ccb863cb1171 Mon Sep 17 00:00:00 2001 From: Marcono1234 Date: Wed, 29 Sep 2021 00:34:35 +0200 Subject: [PATCH 2/2] Improve TreeTypeAdapter thread race comment --- .../java/com/google/gson/internal/bind/TreeTypeAdapter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gson/src/main/java/com/google/gson/internal/bind/TreeTypeAdapter.java b/gson/src/main/java/com/google/gson/internal/bind/TreeTypeAdapter.java index bc26ea8898..03dfc32631 100644 --- a/gson/src/main/java/com/google/gson/internal/bind/TreeTypeAdapter.java +++ b/gson/src/main/java/com/google/gson/internal/bind/TreeTypeAdapter.java @@ -83,7 +83,7 @@ public TreeTypeAdapter(JsonSerializer serializer, JsonDeserializer deseria } private TypeAdapter delegate() { - // Allows racy initialization of `delegate` by multiple threads + // A race might lead to `delegate` being assigned by multiple threads but the last assignment will stick TypeAdapter d = delegate; return d != null ? d