diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2015-12-04 17:32:40 +0000 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2015-12-04 17:32:40 +0000 |
commit | 755be51d0266bc008def4de484cc9c7803283d69 (patch) | |
tree | 497aba097b51602810d2e63632cc24a664634e0f | |
parent | 586cdac8e5af3fff142829e579558f8728e56f81 (diff) | |
download | gcc-755be51d0266bc008def4de484cc9c7803283d69.zip gcc-755be51d0266bc008def4de484cc9c7803283d69.tar.gz gcc-755be51d0266bc008def4de484cc9c7803283d69.tar.bz2 |
PR libstdc++/57060 cope with invalid thread IDs
PR libstdc++/57060
* include/std/thread (operator==(thread::id, thread::id)): Do not use
__gthread_equal.
(operator<(thread::id, thread::id)): Add comment.
(this_thread::get_id()): Do not use __gthread_self for single-threaded
programs using glibc.
* testsuite/30_threads/this_thread/57060.cc: New.
From-SVN: r231289
-rw-r--r-- | libstdc++-v3/ChangeLog | 10 | ||||
-rw-r--r-- | libstdc++-v3/include/std/thread | 27 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/30_threads/this_thread/57060.cc | 37 |
3 files changed, 71 insertions, 3 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index eafe38c..f77428e 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,13 @@ +2015-12-04 Jonathan Wakely <jwakely@redhat.com> + + PR libstdc++/57060 + * include/std/thread (operator==(thread::id, thread::id)): Do not use + __gthread_equal. + (operator<(thread::id, thread::id)): Add comment. + (this_thread::get_id()): Do not use __gthread_self for single-threaded + programs using glibc. + * testsuite/30_threads/this_thread/57060.cc: New. + 2015-12-02 Jonathan Wakely <jwakely@redhat.com> PR libstdc++/56383 diff --git a/libstdc++-v3/include/std/thread b/libstdc++-v3/include/std/thread index 8c01feb..efdd83e 100644 --- a/libstdc++-v3/include/std/thread +++ b/libstdc++-v3/include/std/thread @@ -89,11 +89,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION friend bool operator==(thread::id __x, thread::id __y) noexcept - { return __gthread_equal(__x._M_thread, __y._M_thread); } + { + // pthread_equal is undefined if either thread ID is not valid, so we + // can't safely use __gthread_equal on default-constructed values (nor + // the non-zero value returned by this_thread::get_id() for + // single-threaded programs using GNU libc). Assume EqualityComparable. + return __x._M_thread == __y._M_thread; + } friend bool operator<(thread::id __x, thread::id __y) noexcept - { return __x._M_thread < __y._M_thread; } + { + // Pthreads doesn't define any way to do this, so we just have to + // assume native_handle_type is LessThanComparable. + return __x._M_thread < __y._M_thread; + } template<class _CharT, class _Traits> friend basic_ostream<_CharT, _Traits>& @@ -269,7 +279,18 @@ _GLIBCXX_END_NAMESPACE_VERSION /// get_id inline thread::id - get_id() noexcept { return thread::id(__gthread_self()); } + get_id() noexcept + { +#ifdef __GLIBC__ + // For the GNU C library pthread_self() is usable without linking to + // libpthread.so but returns 0, so we cannot use it in single-threaded + // programs, because this_thread::get_id() != thread::id{} must be true. + // We know that pthread_t is an integral type in the GNU C library. + if (!__gthread_active_p()) + return thread::id(1); +#endif + return thread::id(__gthread_self()); + } /// yield inline void diff --git a/libstdc++-v3/testsuite/30_threads/this_thread/57060.cc b/libstdc++-v3/testsuite/30_threads/this_thread/57060.cc new file mode 100644 index 0000000..c932719 --- /dev/null +++ b/libstdc++-v3/testsuite/30_threads/this_thread/57060.cc @@ -0,0 +1,37 @@ +// Copyright (C) 2015 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +// { dg-do run { target *-*-gnu* } } +// { dg-options "-std=gnu++11" } +// { dg-require-gthreads "" } + +// N.B. this test intentionally does *not* use -pthread + +#include <thread> +#include <testsuite_hooks.h> + +void +test01() +{ + VERIFY( std::this_thread::get_id() != std::thread::id() ); +} + +int +main() +{ + test01(); +} |