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:
Jonathan Wakely 2012-08-25 23:06:07 +00:00 committed by Jonathan Wakely
parent b4265383ce
commit 81c69fe1d5
4 changed files with 67 additions and 2 deletions

View File

@ -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

View File

@ -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;

View File

@ -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.

View File

@ -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());
}