diff --git a/runtime/Cpp/runtime/CMakeLists.txt b/runtime/Cpp/runtime/CMakeLists.txt index a4e4d1c6b09..47497d566ed 100644 --- a/runtime/Cpp/runtime/CMakeLists.txt +++ b/runtime/Cpp/runtime/CMakeLists.txt @@ -28,13 +28,6 @@ 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 4f969a8ab64..ff4d793ae6b 100644 --- a/runtime/Cpp/runtime/src/internal/Synchronization.h +++ b/runtime/Cpp/runtime/src/internal/Synchronization.h @@ -27,12 +27,13 @@ #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 @@ -135,20 +136,15 @@ namespace antlr4::internal { template friend void call_once(OnceFlag &onceFlag, Callable &&callable, Args&&... args); -#if ANTLR4CPP_USING_ABSEIL - absl::once_flag _impl; -#else - std::once_flag _impl; -#endif + std::atomic_flag _flag = false; }; template - 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 + void call_once(OnceFlag &onceFlag, Callable &&callable, Args &&...args) { + if (onceFlag._flag.test_and_set()) { + return; + } + std::invoke(std::forward(callable), std::forward(args)...); } } // namespace antlr4::internal