This is an automated email from the ASF dual-hosted git repository.

yiguolei pushed a commit to branch branch-4.0
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-4.0 by this push:
     new 7b1338085a3 branch-4.0: [fix](inverted index) fix data race in 
AnalysisFactoryMgr causing std::bad_function_call crash #61077 (#61098)
7b1338085a3 is described below

commit 7b1338085a3e92f3d0ed67d77ead480430aeb56b
Author: github-actions[bot] 
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Fri Mar 6 13:56:04 2026 +0800

    branch-4.0: [fix](inverted index) fix data race in AnalysisFactoryMgr 
causing std::bad_function_call crash #61077 (#61098)
    
    Cherry-picked from #61077
    
    Co-authored-by: zzzxl <[email protected]>
---
 .../inverted_index/analysis_factory_mgr.cpp        |  4 +-
 .../inverted_index/analysis_factory_mgr_test.cpp   | 44 ++++++++++++++++++++++
 2 files changed, 45 insertions(+), 3 deletions(-)

diff --git 
a/be/src/olap/rowset/segment_v2/inverted_index/analysis_factory_mgr.cpp 
b/be/src/olap/rowset/segment_v2/inverted_index/analysis_factory_mgr.cpp
index 0dfbd9f134e..dc5fcc42293 100644
--- a/be/src/olap/rowset/segment_v2/inverted_index/analysis_factory_mgr.cpp
+++ b/be/src/olap/rowset/segment_v2/inverted_index/analysis_factory_mgr.cpp
@@ -94,9 +94,7 @@ void AnalysisFactoryMgr::registerFactory(const std::string& 
name, FactoryCreator
 template <typename FactoryType>
 std::shared_ptr<FactoryType> AnalysisFactoryMgr::create(const std::string& 
name,
                                                         const Settings& 
params) {
-    if (registry_.empty()) {
-        initialise();
-    }
+    initialise();
 
     RegistryKey key = {std::type_index(typeid(FactoryType)), name};
     auto it = registry_.find(key);
diff --git 
a/be/test/olap/rowset/segment_v2/inverted_index/analysis_factory_mgr_test.cpp 
b/be/test/olap/rowset/segment_v2/inverted_index/analysis_factory_mgr_test.cpp
index 7f061fbce7a..c28a8d258bd 100644
--- 
a/be/test/olap/rowset/segment_v2/inverted_index/analysis_factory_mgr_test.cpp
+++ 
b/be/test/olap/rowset/segment_v2/inverted_index/analysis_factory_mgr_test.cpp
@@ -19,6 +19,10 @@
 
 #include <gtest/gtest.h>
 
+#include <atomic>
+#include <thread>
+#include <vector>
+
 #include 
"olap/rowset/segment_v2/inverted_index/char_filter/char_filter_factory.h"
 #include 
"olap/rowset/segment_v2/inverted_index/char_filter/empty_char_filter_factory.h"
 #include 
"olap/rowset/segment_v2/inverted_index/token_filter/empty_token_filter_factory.h"
@@ -246,4 +250,44 @@ TEST_F(AnalysisFactoryMgrTest, 
TypeSafetyForDifferentFactoryTypes) {
                  Exception);
 }
 
+TEST_F(AnalysisFactoryMgrTest, ConcurrentCreateIsThreadSafe) {
+    constexpr int kNumThreads = 16;
+    constexpr int kIterationsPerThread = 100;
+
+    std::vector<std::thread> threads;
+    std::atomic<int> success_count {0};
+    std::atomic<int> failure_count {0};
+
+    for (int i = 0; i < kNumThreads; ++i) {
+        threads.emplace_back([&]() {
+            Settings empty_settings;
+            std::vector<std::string> tokenizer_names = {"standard", "keyword", 
"basic", "icu"};
+            std::vector<std::string> filter_names = {"lowercase", 
"asciifolding"};
+
+            for (int j = 0; j < kIterationsPerThread; ++j) {
+                try {
+                    auto tk = 
AnalysisFactoryMgr::instance().create<TokenizerFactory>(
+                            tokenizer_names[j % tokenizer_names.size()], 
empty_settings);
+                    ASSERT_NE(tk, nullptr);
+
+                    auto tf = 
AnalysisFactoryMgr::instance().create<TokenFilterFactory>(
+                            filter_names[j % filter_names.size()], 
empty_settings);
+                    ASSERT_NE(tf, nullptr);
+
+                    success_count.fetch_add(1, std::memory_order_relaxed);
+                } catch (...) {
+                    failure_count.fetch_add(1, std::memory_order_relaxed);
+                }
+            }
+        });
+    }
+
+    for (auto& t : threads) {
+        t.join();
+    }
+
+    EXPECT_EQ(failure_count.load(), 0) << "Concurrent create() should not 
throw any exceptions";
+    EXPECT_EQ(success_count.load(), kNumThreads * kIterationsPerThread);
+}
+
 } // namespace doris::segment_v2::inverted_index
\ No newline at end of file


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to