libstdc++: Revert to old std::call_once implementation [PR 99341]
authorJonathan Wakely <jwakely@redhat.com>
Fri, 12 Mar 2021 11:47:20 +0000 (11:47 +0000)
committerJonathan Wakely <jwakely@redhat.com>
Tue, 16 Mar 2021 12:25:28 +0000 (12:25 +0000)
commit6ee24638ed0ad51e568c799bacf149ba9bd7628b
tree4066b8acc330b4f0f62fc4a1392908988306e160
parent7b900dca607dceaae2db372365f682a4979c7826
libstdc++: Revert to old std::call_once implementation [PR 99341]

The new std::call_once implementation is not backwards compatible,
contrary to my intention. Because std::once_flag::_M_active() doesn't
write glibc's "fork generation" into the pthread_once_t object, it's
possible for glibc and libstdc++ to run two active executions
concurrently. This violates the primary invariant of the feature!

This patch reverts std::once_flag and std::call_once to the old
implementation that uses pthread_once. This means PR 66146 is a problem
again, but glibc has been changed to solve that. A new API similar to
pthread_once but supporting failure and resetting the pthread_once_t
will be proposed for inclusion in glibc and other C libraries.

This change doesn't simply revert r11-4691 because I want to retain the
new implementation for non-ghtreads targets (which didn't previously
support std::call_once at all, so there's no backwards compatibility
concern). This also leaves the new std::call_once::_M_activate() and
std::call_once::_M_finish(bool) symbols present in libstdc++.so.6 so
that code already compiled against GCC 11 can still use them. Those
symbols will be removed in a subsequent commit (which distros can choose
to temporarily revert if needed).

libstdc++-v3/ChangeLog:

PR libstdc++/99341
* include/std/mutex [_GLIBCXX_HAVE_LINUX_FUTEX] (once_flag):
Revert to pthread_once_t implementation.
[_GLIBCXX_HAVE_LINUX_FUTEX] (call_once): Likewise.
* src/c++11/mutex.cc [_GLIBCXX_HAVE_LINUX_FUTEX]
(struct __once_flag_compat): New type matching the reverted
implementation of once_flag using futexes.
(once_flag::_M_activate): Remove, replace with ...
(_ZNSt9once_flag11_M_activateEv): ... alias symbol.
(once_flag::_M_finish): Remove, replace with ...
(_ZNSt9once_flag9_M_finishEb): ... alias symbol.
* testsuite/30_threads/call_once/66146.cc: Removed.
libstdc++-v3/include/std/mutex
libstdc++-v3/src/c++11/mutex.cc
libstdc++-v3/testsuite/30_threads/call_once/66146.cc [deleted file]