re PR libstdc++/54297 ([C++11] Segmentation fault with std::async and released shared state)
PR libstdc++/54297 * include/std/future (~_Async_state_impl): Join thread before derived class members are destroyed. (~_Async_state_common): Only define non-trivial destructor when included from future.cc for ABI compatibility reasons. * src/c++11/future.cc (_GLIBCXX_ABI_COMPAT_ASYNC): Define. * testsuite/30_threads/async/54297.cc: New. From-SVN: r190673
This commit is contained in:
parent
b4265383ce
commit
81c69fe1d5
|
@ -1,3 +1,13 @@
|
|||
2012-08-25 Jonathan Wakely <jwakely.gcc@gmail.com>
|
||||
|
||||
PR libstdc++/54297
|
||||
* include/std/future (~_Async_state_impl): Join thread before
|
||||
derived class members are destroyed.
|
||||
(~_Async_state_common): Only define non-trivial destructor when
|
||||
included from future.cc for ABI compatibility reasons.
|
||||
* src/c++11/future.cc (_GLIBCXX_ABI_COMPAT_ASYNC): Define.
|
||||
* testsuite/30_threads/async/54297.cc: New.
|
||||
|
||||
2012-08-13 David Adler <d.adler.s@gmail.com>
|
||||
|
||||
PR libstdc++/54185
|
||||
|
|
|
@ -1425,10 +1425,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
class __future_base::_Async_state_common : public __future_base::_State_base
|
||||
{
|
||||
protected:
|
||||
#ifdef _GLIBCXX_HAVE_TLS
|
||||
#if defined(_GLIBCXX_HAVE_TLS) && defined(_GLIBCXX_ABI_COMPAT_ASYNC)
|
||||
~_Async_state_common();
|
||||
#else
|
||||
~_Async_state_common() { _M_join(); }
|
||||
~_Async_state_common() = default;
|
||||
#endif
|
||||
|
||||
// Allow non-timed waiting functions to block until the thread completes,
|
||||
|
@ -1455,6 +1455,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
} };
|
||||
}
|
||||
|
||||
~_Async_state_impl() { _M_join(); }
|
||||
|
||||
private:
|
||||
typedef __future_base::_Ptr<_Result<_Res>> _Ptr_type;
|
||||
_Ptr_type _M_result;
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
#define _GLIBCXX_ABI_COMPAT_ASYNC
|
||||
|
||||
#include <future>
|
||||
|
||||
namespace
|
||||
|
@ -86,6 +88,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
__future_base::_State_base::~_State_base() = default;
|
||||
|
||||
#ifdef _GLIBCXX_HAVE_TLS
|
||||
// Exported for compatibility with ABI version 3.4.17
|
||||
__future_base::_Async_state_common::~_Async_state_common() { _M_join(); }
|
||||
|
||||
// Explicit instantiation due to -fno-implicit-instantiation.
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
// { dg-do run { target *-*-freebsd* *-*-netbsd* *-*-linux* *-*-solaris* *-*-cygwin *-*-darwin* powerpc-ibm-aix* } }
|
||||
// { dg-options " -std=gnu++0x -pthread" { target *-*-freebsd* *-*-netbsd* *-*-linux* powerpc-ibm-aix* } }
|
||||
// { dg-options " -std=gnu++0x -pthreads" { target *-*-solaris* } }
|
||||
// { dg-options " -std=gnu++0x " { target *-*-cygwin *-*-darwin* } }
|
||||
// { dg-require-cstdint "" }
|
||||
// { dg-require-gthreads "" }
|
||||
// { dg-require-atomic-builtins "" }
|
||||
|
||||
// Copyright (C) 2012 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/>.
|
||||
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
#include <future>
|
||||
#include <set>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
struct Task;
|
||||
|
||||
std::set<const Task*> dead_tasks;
|
||||
|
||||
struct Task
|
||||
{
|
||||
~Task() { dead_tasks.insert(this); }
|
||||
|
||||
void operator()() const
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
VERIFY( dead_tasks.count(this) == 0 );
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
std::async(std::launch::async, Task());
|
||||
}
|
Loading…
Reference in New Issue