From a156a06a5f0daac684e22febf9b80c2f583bc7ab Mon Sep 17 00:00:00 2001 From: Terence Parr Date: Sun, 19 Feb 2023 11:43:21 -0800 Subject: [PATCH] Revert "cpp runtime: Remove pthread dependency. (#4086)" This reverts commit 207314792d851bcb11a409ce46ca34f37fd22fbd. --- runtime/Cpp/runtime/CMakeLists.txt | 7 +++++++ .../runtime/src/internal/Synchronization.h | 20 +++++++++++-------- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/runtime/Cpp/runtime/CMakeLists.txt b/runtime/Cpp/runtime/CMakeLists.txt index 47497d566e..a4e4d1c6b0 100644 --- a/runtime/Cpp/runtime/CMakeLists.txt +++ b/runtime/Cpp/runtime/CMakeLists.txt @@ -28,6 +28,13 @@ file(GLOB libantlrcpp_SRC add_library(antlr4_shared SHARED ${libantlrcpp_SRC}) add_library(antlr4_static STATIC ${libantlrcpp_SRC}) +# Make sure to link against threads (pthreads) library in order to be able to +# make use of std::call_once in the code without producing runtime errors +# (see also https://github.com/antlr/antlr4/issues/3708 and/or https://stackoverflow.com/q/51584960). +find_package(Threads REQUIRED) +target_link_libraries(antlr4_shared Threads::Threads) +target_link_libraries(antlr4_static Threads::Threads) + if (ANTLR_BUILD_CPP_TESTS) include(FetchContent) diff --git a/runtime/Cpp/runtime/src/internal/Synchronization.h b/runtime/Cpp/runtime/src/internal/Synchronization.h index 1c20338f09..4f969a8ab6 100644 --- a/runtime/Cpp/runtime/src/internal/Synchronization.h +++ b/runtime/Cpp/runtime/src/internal/Synchronization.h @@ -27,13 +27,12 @@ #include "antlr4-common.h" -#include -#include #include #include #include #if ANTLR4CPP_USING_ABSEIL +#include "absl/base/call_once.h" #include "absl/base/thread_annotations.h" #include "absl/synchronization/mutex.h" #define ANTLR4CPP_NO_THREAD_SAFTEY_ANALYSIS ABSL_NO_THREAD_SAFETY_ANALYSIS @@ -136,15 +135,20 @@ namespace antlr4::internal { template friend void call_once(OnceFlag &onceFlag, Callable &&callable, Args&&... args); - std::atomic_flag _flag = ATOMIC_FLAG_INIT; +#if ANTLR4CPP_USING_ABSEIL + absl::once_flag _impl; +#else + std::once_flag _impl; +#endif }; template - void call_once(OnceFlag &onceFlag, Callable &&callable, Args &&...args) { - if (onceFlag._flag.test_and_set()) { - return; - } - std::invoke(std::forward(callable), std::forward(args)...); + void call_once(OnceFlag &onceFlag, Callable &&callable, Args&&... args) { +#if ANTLR4CPP_USING_ABSEIL + absl::call_once(onceFlag._impl, std::forward(callable), std::forward(args)...); +#else + std::call_once(onceFlag._impl, std::forward(callable), std::forward(args)...); +#endif } } // namespace antlr4::internal