From c11687e8b3a487045f64837a74c5673cda6fd5db Mon Sep 17 00:00:00 2001 From: daguimu Date: Wed, 25 Mar 2026 19:42:22 +0800 Subject: [PATCH] fix: use thread-safe collections in SchemaDescriptorRegistry SchemaDescriptorRegistry has three thread-safety issues: 1. SERVICES uses a plain HashSet accessed concurrently during service registration. Concurrent HashSet.add() can corrupt internal state. 2. addExtension() has a check-then-act race on EXTENSIONS: two threads can both see containsKey()==false, both put a new HashMap, and one overwrites the other's entries. 3. The inner HashMap in EXTENSIONS is also accessed concurrently via fdMap.put() without synchronization. Fix: Replace HashSet with ConcurrentHashMap.newKeySet(), replace check-then-act with computeIfAbsent(), and use ConcurrentHashMap for the inner map. --- .../protocol/tri/service/SchemaDescriptorRegistry.java | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/service/SchemaDescriptorRegistry.java b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/service/SchemaDescriptorRegistry.java index 0eb6fc68256..9a898d2f81b 100644 --- a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/service/SchemaDescriptorRegistry.java +++ b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/service/SchemaDescriptorRegistry.java @@ -18,8 +18,6 @@ import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -35,7 +33,7 @@ public class SchemaDescriptorRegistry { private static final Map> EXTENSIONS = new ConcurrentHashMap<>(); - private static final Set SERVICES = new HashSet<>(); + private static final Set SERVICES = ConcurrentHashMap.newKeySet(); public static void addSchemaDescriptor(String serviceName, FileDescriptor fd) { SERVICES.add(serviceName); @@ -58,11 +56,7 @@ private static void addType(Descriptor descriptor) { private static void addExtension(FieldDescriptor extension, FileDescriptor fd) { String name = extension.getContainingType().getFullName(); int number = extension.getNumber(); - if (!EXTENSIONS.containsKey(name)) { - EXTENSIONS.put(name, new HashMap<>()); - } - Map fdMap = EXTENSIONS.get(name); - fdMap.put(number, fd); + EXTENSIONS.computeIfAbsent(name, k -> new ConcurrentHashMap<>()).put(number, fd); } public static FileDescriptor getFileDescriptorByExtensionAndNumber(String extension, int number) {