This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug libstdc++/39909] New: non-TLS version of std::call_once causes terminate
- From: "jwakely dot gcc at gmail dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 26 Apr 2009 13:51:26 -0000
- Subject: [Bug libstdc++/39909] New: non-TLS version of std::call_once causes terminate
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
I'm entering this bug to track:
http://gcc.gnu.org/ml/libstdc++/2009-04/msg00009.html
The following program fails using gcc configured --disable-tls
#include <mutex>
#include <thread>
#include <assert.h>
std::once_flag flag;
int value = 0;
struct Inc { void operator()() const { ++value; } };
struct Func
{
void operator()() const
{
Inc inc;
for (int i = 0; i < 10000; ++i)
std::call_once(flag, inc);
}
};
int main()
{
Func f;
std::thread t1(f);
std::thread t2(f);
std::thread t3(f);
t1.join();
t2.join();
t3.join();
assert( value == 1 );
return 0;
}
Multiple threads try to call unique_lock<mutex>::lock() on the same object
simultaneously, after the first one acquires the lock the subsequent threads
will fail due to this check in unique_lock::lock()
else if (_M_owns)
__throw_system_error(int(errc::resource_deadlock_would_occur));
The unhandled exceptions terminate the program.
The obvious fix is to stop using a single, global lock object shared between
all threads, and use a different lock object in each thread's stack, sharing a
global mutex. Concurrent operations on a single mutex are safe, but not on a
single lock.
That fix requires an ABI change, since __get_once_functor_lock is exported. An
alternative would be to replicate the code used when TLS is available, but
using pthread_getspecific / pthread_setspecific instead.
--
Summary: non-TLS version of std::call_once causes terminate
Product: gcc
Version: 4.4.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: libstdc++
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: jwakely dot gcc at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39909