From 9d90f099b0aa6874826c85e7db390cee5ced1fba Mon Sep 17 00:00:00 2001 From: Alirana2829 Date: Fri, 30 Jan 2026 15:18:12 +0500 Subject: [PATCH] GH-49064: [C++] Fix thread safety in DictionaryArray::dictionary() The dictionary() method was doing lazy initialization without thread safety, causing potential race conditions when multiple threads access the same DictionaryArray instance. This could lead to memory corruption or double-free errors. Fixed by using std::call_once with std::once_flag to ensure the dictionary is initialized exactly once in a thread-safe manner. Closes #49064 --- cpp/src/arrow/array/array_dict.cc | 7 +++---- cpp/src/arrow/array/array_dict.h | 2 ++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/cpp/src/arrow/array/array_dict.cc b/cpp/src/arrow/array/array_dict.cc index 2e54e6ec4904..25bf381bbb6a 100644 --- a/cpp/src/arrow/array/array_dict.cc +++ b/cpp/src/arrow/array/array_dict.cc @@ -108,10 +108,9 @@ DictionaryArray::DictionaryArray(const std::shared_ptr& type, } const std::shared_ptr& DictionaryArray::dictionary() const { - if (!dictionary_) { - // TODO(GH-36503) this isn't thread safe - dictionary_ = MakeArray(data_->dictionary); - } + std::call_once(dict_init_flag_, [this]() { + const_cast(this)->dictionary_ = MakeArray(data_->dictionary); + }); return dictionary_; } diff --git a/cpp/src/arrow/array/array_dict.h b/cpp/src/arrow/array/array_dict.h index bf376b51f8c9..8d8e1bfe69a3 100644 --- a/cpp/src/arrow/array/array_dict.h +++ b/cpp/src/arrow/array/array_dict.h @@ -19,6 +19,7 @@ #include #include +#include #include "arrow/array/array_base.h" #include "arrow/array/data.h" @@ -120,6 +121,7 @@ class ARROW_EXPORT DictionaryArray : public Array { // Lazily initialized when invoking dictionary() mutable std::shared_ptr dictionary_; + mutable std::once_flag dict_init_flag_; }; /// \brief Helper class for incremental dictionary unification