Skip to content

Commit

Permalink
cpp runtime: Remove pthread dependency.
Browse files Browse the repository at this point in the history
ANTLR doesn't use threads, and it used not to depend on pthread library
either.

It changed recently in 2022: antlr#3708
The patch linked against pthread, because the GNU libstdc++ used to
depend on it in their implementation of `std::call_once`.

By the way, the libstdc++ stopped it in 2020:
https://gcc.gnu.org/git/gitweb.cgi?p=gcc.git;h=93e79ed391b9c636f087e6eb7e70f14963cd10ad
So this is not more needed.

I would like to stop depending on pthread. I am using ANTLR in C++
WebAssembly for the website:
https://arthursonzogni.com/Diagon/

It doesn't compile with emscripten anymore, because by default pthread
is not enabled. It could be enabled, but it would force me to deploy
cross-origin-isolation:
https://web.dev/cross-origin-isolation-guide/

Solutions:
1. Stop linking against pthread, because the libstdc++ stopped depending
   on it for std::call_once.
2. Implement std::call_once ourself using std::atomic_flag
3. Implement std::call_once ourself using a boolean flag, assuming we
   don't need to support threads.

I chose to do (2) in this patch.
  • Loading branch information
ArthurSonzogni committed Jan 22, 2023
1 parent 76fa05c commit 99efe4d
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 19 deletions.
7 changes: 0 additions & 7 deletions runtime/Cpp/runtime/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
20 changes: 8 additions & 12 deletions runtime/Cpp/runtime/src/internal/Synchronization.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,13 @@

#include "antlr4-common.h"

#include <atomic>
#include <functional>
#include <mutex>
#include <shared_mutex>
#include <utility>

#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
Expand Down Expand Up @@ -135,20 +136,15 @@ namespace antlr4::internal {
template <typename Callable, typename... Args>
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 <typename Callable, typename... Args>
void call_once(OnceFlag &onceFlag, Callable &&callable, Args&&... args) {
#if ANTLR4CPP_USING_ABSEIL
absl::call_once(onceFlag._impl, std::forward<Callable>(callable), std::forward<Args>(args)...);
#else
std::call_once(onceFlag._impl, std::forward<Callable>(callable), std::forward<Args>(args)...);
#endif
void call_once(OnceFlag &onceFlag, Callable &&callable, Args &&...args) {
if (onceFlag._flag.test_and_set()) {
return;
}
std::invoke(std::forward<Callable>(callable), std::forward<Args>(args)...);
}

} // namespace antlr4::internal

0 comments on commit 99efe4d

Please sign in to comment.