mirror of git://gcc.gnu.org/git/gcc.git
condition_variable (condition_variable_any::_Unlock): Do not swallow __forced_unwind.
* include/std/condition_variable (condition_variable_any::_Unlock): Do not swallow __forced_unwind. * include/std/future (__future_base::_Task_setter): Likewise. (__future_base::_Async_state_impl): Turn __forced_unwind into broken promise and rethrow. * include/std/mutex (try_lock): Likewise. * testsuite/30_threads/async/forced_unwind.cc: New. * testsuite/30_threads/packaged_task/forced_unwind.cc: New. From-SVN: r211138
This commit is contained in:
parent
d371802725
commit
315eb4bb08
|
|
@ -1,3 +1,14 @@
|
||||||
|
2014-06-02 Jonathan Wakely <jwakely@redhat.com>
|
||||||
|
|
||||||
|
* include/std/condition_variable (condition_variable_any::_Unlock): Do
|
||||||
|
not swallow __forced_unwind.
|
||||||
|
* include/std/future (__future_base::_Task_setter): Likewise.
|
||||||
|
(__future_base::_Async_state_impl): Turn __forced_unwind into broken
|
||||||
|
promise and rethrow.
|
||||||
|
* include/std/mutex (try_lock): Likewise.
|
||||||
|
* testsuite/30_threads/async/forced_unwind.cc: New.
|
||||||
|
* testsuite/30_threads/packaged_task/forced_unwind.cc: New.
|
||||||
|
|
||||||
2014-06-02 Rüdiger Sonderfeld <ruediger@c-plusplus.de>
|
2014-06-02 Rüdiger Sonderfeld <ruediger@c-plusplus.de>
|
||||||
Jonathan Wakely <jwakely@redhat.com>
|
Jonathan Wakely <jwakely@redhat.com>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -189,7 +189,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
~_Unlock() noexcept(false)
|
~_Unlock() noexcept(false)
|
||||||
{
|
{
|
||||||
if (uncaught_exception())
|
if (uncaught_exception())
|
||||||
__try { _M_lock.lock(); } __catch(...) { }
|
{
|
||||||
|
__try
|
||||||
|
{ _M_lock.lock(); }
|
||||||
|
__catch(const __cxxabiv1::__forced_unwind&)
|
||||||
|
{ __throw_exception_again; }
|
||||||
|
__catch(...)
|
||||||
|
{ }
|
||||||
|
}
|
||||||
else
|
else
|
||||||
_M_lock.lock();
|
_M_lock.lock();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1230,6 +1230,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
{
|
{
|
||||||
_M_result->_M_set(_M_fn());
|
_M_result->_M_set(_M_fn());
|
||||||
}
|
}
|
||||||
|
__catch(const __cxxabiv1::__forced_unwind&)
|
||||||
|
{
|
||||||
|
__throw_exception_again; // will cause broken_promise
|
||||||
|
}
|
||||||
__catch(...)
|
__catch(...)
|
||||||
{
|
{
|
||||||
_M_result->_M_error = current_exception();
|
_M_result->_M_error = current_exception();
|
||||||
|
|
@ -1249,6 +1253,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
{
|
{
|
||||||
_M_fn();
|
_M_fn();
|
||||||
}
|
}
|
||||||
|
__catch(const __cxxabiv1::__forced_unwind&)
|
||||||
|
{
|
||||||
|
__throw_exception_again; // will cause broken_promise
|
||||||
|
}
|
||||||
__catch(...)
|
__catch(...)
|
||||||
{
|
{
|
||||||
_M_result->_M_error = current_exception();
|
_M_result->_M_error = current_exception();
|
||||||
|
|
@ -1509,7 +1517,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
: _M_result(new _Result<_Res>()), _M_fn(std::move(__fn))
|
: _M_result(new _Result<_Res>()), _M_fn(std::move(__fn))
|
||||||
{
|
{
|
||||||
_M_thread = std::thread{ [this] {
|
_M_thread = std::thread{ [this] {
|
||||||
|
__try
|
||||||
|
{
|
||||||
_M_set_result(_S_task_setter(_M_result, _M_fn));
|
_M_set_result(_S_task_setter(_M_result, _M_fn));
|
||||||
|
}
|
||||||
|
__catch (const __cxxabiv1::__forced_unwind&)
|
||||||
|
{
|
||||||
|
// make the shared state ready on thread cancellation
|
||||||
|
if (static_cast<bool>(_M_result))
|
||||||
|
this->_M_break_promise(std::move(_M_result));
|
||||||
|
__throw_exception_again;
|
||||||
|
}
|
||||||
} };
|
} };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@
|
||||||
#include <bits/functexcept.h>
|
#include <bits/functexcept.h>
|
||||||
#include <bits/gthr.h>
|
#include <bits/gthr.h>
|
||||||
#include <bits/move.h> // for std::swap
|
#include <bits/move.h> // for std::swap
|
||||||
|
#include <bits/cxxabi_forced.h>
|
||||||
|
|
||||||
#ifdef _GLIBCXX_USE_C99_STDINT_TR1
|
#ifdef _GLIBCXX_USE_C99_STDINT_TR1
|
||||||
|
|
||||||
|
|
@ -631,6 +632,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
auto __locks = std::tie(__l1, __l2, __l3...);
|
auto __locks = std::tie(__l1, __l2, __l3...);
|
||||||
__try
|
__try
|
||||||
{ __try_lock_impl<0>::__do_try_lock(__locks, __idx); }
|
{ __try_lock_impl<0>::__do_try_lock(__locks, __idx); }
|
||||||
|
__catch(const __cxxabiv1::__forced_unwind&)
|
||||||
|
{ __throw_exception_again; }
|
||||||
__catch(...)
|
__catch(...)
|
||||||
{ }
|
{ }
|
||||||
return __idx;
|
return __idx;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
// { dg-do run { target *-*-linux* *-*-gnu* } }
|
||||||
|
// { dg-options " -std=gnu++11 -pthread" { target *-*-linux* *-*-gnu* } }
|
||||||
|
// { dg-require-cstdint "" }
|
||||||
|
// { dg-require-gthreads "" }
|
||||||
|
// { dg-require-atomic-builtins "" }
|
||||||
|
|
||||||
|
// Copyright (C) 2014 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/>.
|
||||||
|
|
||||||
|
// Test (non-standard) handling of __forced_unwind exception.
|
||||||
|
|
||||||
|
#include <future>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <testsuite_hooks.h>
|
||||||
|
|
||||||
|
void f() { pthread_exit(nullptr); }
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
auto fut = std::async(std::launch::async, f);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
fut.get();
|
||||||
|
throw std::logic_error("Unreachable");
|
||||||
|
}
|
||||||
|
catch (const std::future_error& e)
|
||||||
|
{
|
||||||
|
VERIFY( e.code() == std::future_errc::broken_promise );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
// { dg-do run { target *-*-linux* *-*-gnu* } }
|
||||||
|
// { dg-options " -std=gnu++11 -pthread" { target *-*-linux* *-*-gnu* } }
|
||||||
|
// { dg-require-cstdint "" }
|
||||||
|
// { dg-require-gthreads "" }
|
||||||
|
// { dg-require-atomic-builtins "" }
|
||||||
|
|
||||||
|
// Copyright (C) 2014 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/>.
|
||||||
|
|
||||||
|
// Test (non-standard) handling of __forced_unwind exception.
|
||||||
|
|
||||||
|
#include <future>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <testsuite_hooks.h>
|
||||||
|
|
||||||
|
void f() { pthread_exit(nullptr); }
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
std::packaged_task<void()> p(f);
|
||||||
|
auto fut = p.get_future();
|
||||||
|
std::thread t(std::move(p));
|
||||||
|
try
|
||||||
|
{
|
||||||
|
fut.get();
|
||||||
|
throw std::logic_error("Unreachable");
|
||||||
|
}
|
||||||
|
catch (const std::future_error& e)
|
||||||
|
{
|
||||||
|
VERIFY( e.code() == std::future_errc::broken_promise );
|
||||||
|
}
|
||||||
|
t.join();
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue