From decba3f33f2a4969240fece15663de34daad45ed Mon Sep 17 00:00:00 2001 From: Oliver Kowalke Date: Tue, 1 Oct 2013 19:44:06 +0200 Subject: [PATCH] std::terminate() called if exception not catched --- include/boost/fiber/detail/fiber_base.hpp | 3 -- src/detail/fiber_base.cpp | 8 +++- src/fiber.cpp | 22 ++++++----- src/interruption.cpp | 2 +- src/mutex.cpp | 48 +++++++++-------------- src/recursive_mutex.cpp | 48 +++++++++-------------- src/recursive_timed_mutex.cpp | 48 +++++++++-------------- src/round_robin.cpp | 33 ++++------------ src/timed_mutex.cpp | 48 +++++++++-------------- test/test_fiber.cpp | 26 ++++++------ 10 files changed, 117 insertions(+), 169 deletions(-) diff --git a/include/boost/fiber/detail/fiber_base.hpp b/include/boost/fiber/detail/fiber_base.hpp index 6bd88b4d..68d1d80a 100644 --- a/include/boost/fiber/detail/fiber_base.hpp +++ b/include/boost/fiber/detail/fiber_base.hpp @@ -198,9 +198,6 @@ public: bool join( ptr_t const&); - bool interruption_enabled() const BOOST_NOEXCEPT - { return 0 == ( flags_ & flag_interruption_blocked); } - bool interruption_blocked() const BOOST_NOEXCEPT { return 0 != ( flags_ & flag_interruption_blocked); } diff --git a/src/detail/fiber_base.cpp b/src/detail/fiber_base.cpp index ae6dcfe7..fa7a28a1 100644 --- a/src/detail/fiber_base.cpp +++ b/src/detail/fiber_base.cpp @@ -6,11 +6,14 @@ #include "boost/fiber/detail/fiber_base.hpp" +#include + #include #include #include #include "boost/fiber/detail/scheduler.hpp" +#include #ifdef BOOST_HAS_ABI_HEADERS # include BOOST_ABI_PREFIX @@ -50,8 +53,10 @@ fiber_base::trampoline_( coro::coroutine< void >::push_type & c) release(); throw; } - catch (...) + catch ( fiber_interrupted const&) { except_ = current_exception(); } + catch (...) + { std::terminate(); } set_terminated_(); release(); @@ -73,7 +78,6 @@ fiber_base::resume() BOOST_ASSERT( is_running() ); // set by the scheduler-algorithm caller_(); - if ( has_exception() ) rethrow(); } void diff --git a/src/fiber.cpp b/src/fiber.cpp index f7f4243c..731165d0 100644 --- a/src/fiber.cpp +++ b/src/fiber.cpp @@ -24,7 +24,12 @@ namespace fibers { void fiber::start_fiber_() -{ detail::scheduler::instance()->spawn( impl_); } +{ + detail::scheduler::instance()->spawn( impl_); + // check if joined fiber was interrupted + if ( impl_->has_exception() ) + impl_->rethrow(); +} int fiber::priority() const BOOST_NOEXCEPT @@ -59,14 +64,13 @@ fiber::join() system::errc::invalid_argument, "boost fiber: fiber not joinable") ); } - try - { detail::scheduler::instance()->join( impl_); } - catch (...) - { - impl_.reset(); - throw; - } - impl_.reset(); + detail::scheduler::instance()->join( impl_); + + ptr_t tmp; + tmp.swap( impl_); + // check if joined fiber was interrupted + if ( tmp->has_exception() ) + tmp->rethrow(); } void diff --git a/src/interruption.cpp b/src/interruption.cpp index bfea0bb9..b2dc9469 100644 --- a/src/interruption.cpp +++ b/src/interruption.cpp @@ -51,7 +51,7 @@ restore_interruption::~restore_interruption() BOOST_NOEXCEPT bool interruption_enabled() BOOST_NOEXCEPT { fibers::detail::fiber_base::ptr_t f( fibers::detail::scheduler::instance()->active() ); - return f && f->interruption_enabled(); + return f && ! f->interruption_blocked(); } bool interruption_requested() BOOST_NOEXCEPT diff --git a/src/mutex.cpp b/src/mutex.cpp index aa3a490a..5e247acd 100644 --- a/src/mutex.cpp +++ b/src/mutex.cpp @@ -40,39 +40,29 @@ mutex::lock() while ( LOCKED == state_) { detail::notify::ptr_t n( detail::scheduler::instance()->active() ); - try + if ( n) { - if ( n) - { - // store this fiber in order to be notified later - waiting_.push_back( n); + // store this fiber in order to be notified later + waiting_.push_back( n); - // suspend this fiber - detail::scheduler::instance()->wait(); - } - else - { - // notifier for main-fiber - detail::main_notifier mn; - n = detail::main_notifier::make_pointer( mn); - - // store this fiber in order to be notified later - waiting_.push_back( n); - - // wait until main-fiber gets notified - while ( ! n->is_ready() ) - { - // run scheduler - detail::scheduler::instance()->run(); - } - } + // suspend this fiber + detail::scheduler::instance()->wait(); } - catch (...) + else { - // remove fiber from waiting_ - waiting_.erase( - std::find( waiting_.begin(), waiting_.end(), n) ); - throw; + // notifier for main-fiber + detail::main_notifier mn; + n = detail::main_notifier::make_pointer( mn); + + // store this fiber in order to be notified later + waiting_.push_back( n); + + // wait until main-fiber gets notified + while ( ! n->is_ready() ) + { + // run scheduler + detail::scheduler::instance()->run(); + } } } BOOST_ASSERT( ! owner_); diff --git a/src/recursive_mutex.cpp b/src/recursive_mutex.cpp index 63ff2cc8..a3677166 100644 --- a/src/recursive_mutex.cpp +++ b/src/recursive_mutex.cpp @@ -48,39 +48,29 @@ recursive_mutex::lock() while ( LOCKED == state_) { detail::notify::ptr_t n( detail::scheduler::instance()->active() ); - try + if ( n) { - if ( n) - { - // store this fiber in order to be notified later - waiting_.push_back( n); + // store this fiber in order to be notified later + waiting_.push_back( n); - // suspend this fiber - detail::scheduler::instance()->wait(); - } - else - { - // notifier for main-fiber - detail::main_notifier mn; - n = detail::main_notifier::make_pointer( mn); - - // store this fiber in order to be notified later - waiting_.push_back( n); - - // wait until main-fiber gets notified - while ( ! n->is_ready() ) - { - // run scheduler - detail::scheduler::instance()->run(); - } - } + // suspend this fiber + detail::scheduler::instance()->wait(); } - catch (...) + else { - // remove fiber from waiting_ - waiting_.erase( - std::find( waiting_.begin(), waiting_.end(), n) ); - throw; + // notifier for main-fiber + detail::main_notifier mn; + n = detail::main_notifier::make_pointer( mn); + + // store this fiber in order to be notified later + waiting_.push_back( n); + + // wait until main-fiber gets notified + while ( ! n->is_ready() ) + { + // run scheduler + detail::scheduler::instance()->run(); + } } } BOOST_ASSERT( ! owner_); diff --git a/src/recursive_timed_mutex.cpp b/src/recursive_timed_mutex.cpp index c2443c2b..b8d68f04 100644 --- a/src/recursive_timed_mutex.cpp +++ b/src/recursive_timed_mutex.cpp @@ -48,39 +48,29 @@ recursive_timed_mutex::lock() while ( LOCKED == state_) { detail::notify::ptr_t n( detail::scheduler::instance()->active() ); - try + if ( n) { - if ( n) - { - // store this fiber in order to be notified later - waiting_.push_back( n); + // store this fiber in order to be notified later + waiting_.push_back( n); - // suspend this fiber - detail::scheduler::instance()->wait(); - } - else - { - // notifier for main-fiber - detail::main_notifier mn; - n = detail::main_notifier::make_pointer( mn); - - // store this fiber in order to be notified later - waiting_.push_back( n); - - // wait until main-fiber gets notified - while ( ! n->is_ready() ) - { - // run scheduler - detail::scheduler::instance()->run(); - } - } + // suspend this fiber + detail::scheduler::instance()->wait(); } - catch (...) + else { - // remove fiber from waiting_ - waiting_.erase( - std::find( waiting_.begin(), waiting_.end(), n) ); - throw; + // notifier for main-fiber + detail::main_notifier mn; + n = detail::main_notifier::make_pointer( mn); + + // store this fiber in order to be notified later + waiting_.push_back( n); + + // wait until main-fiber gets notified + while ( ! n->is_ready() ) + { + // run scheduler + detail::scheduler::instance()->run(); + } } } BOOST_ASSERT( ! owner_); diff --git a/src/round_robin.cpp b/src/round_robin.cpp index 8127938a..cf801342 100644 --- a/src/round_robin.cpp +++ b/src/round_robin.cpp @@ -19,7 +19,6 @@ #include "boost/fiber/detail/scheduler.hpp" #include "boost/fiber/exceptions.hpp" -#include "boost/fiber/interruption.hpp" #ifdef BOOST_HAS_ABI_HEADERS # include BOOST_ABI_PREFIX @@ -53,24 +52,15 @@ round_robin::spawn( detail::fiber_base::ptr_t const& f) // store active fiber in local var detail::fiber_base::ptr_t tmp = active_fiber_; - try - { - // assign new fiber to active fiber - active_fiber_ = f; - // set active fiber to state_running - active_fiber_->set_running(); - // resume active fiber - active_fiber_->resume(); - // fiber is resumed + // assign new fiber to active fiber + active_fiber_ = f; + // set active fiber to state_running + active_fiber_->set_running(); + // resume active fiber + active_fiber_->resume(); + // fiber is resumed - BOOST_ASSERT( f == active_fiber_); - } - catch (...) - { - // reset active fiber to previous - active_fiber_ = tmp; - throw; - } + BOOST_ASSERT( f == active_fiber_); // reset active fiber to previous active_fiber_ = tmp; } @@ -196,9 +186,6 @@ round_robin::join( detail::fiber_base::ptr_t const& f) BOOST_ASSERT( tmp == active_fiber_); BOOST_ASSERT( active_fiber_->is_running() ); - - // check if fiber was interrupted - this_fiber::interruption_point(); } else { @@ -206,10 +193,6 @@ round_robin::join( detail::fiber_base::ptr_t const& f) run(); } - // check if joined fiber has an exception - // and rethrow exception - if ( f->has_exception() ) f->rethrow(); - BOOST_ASSERT( f->is_terminated() ); } diff --git a/src/timed_mutex.cpp b/src/timed_mutex.cpp index 21131a75..d8368ca3 100644 --- a/src/timed_mutex.cpp +++ b/src/timed_mutex.cpp @@ -40,39 +40,29 @@ timed_mutex::lock() while ( LOCKED == state_) { detail::notify::ptr_t n( detail::scheduler::instance()->active() ); - try + if ( n) { - if ( n) - { - // store this fiber in order to be notified later - waiting_.push_back( n); + // store this fiber in order to be notified later + waiting_.push_back( n); - // suspend this fiber - detail::scheduler::instance()->wait(); - } - else - { - // notifier for main-fiber - detail::main_notifier mn; - n = detail::main_notifier::make_pointer( mn); - - // store this fiber in order to be notified later - waiting_.push_back( n); - - // wait until main-fiber gets notified - while ( ! n->is_ready() ) - { - // run scheduler - detail::scheduler::instance()->run(); - } - } + // suspend this fiber + detail::scheduler::instance()->wait(); } - catch (...) + else { - // remove fiber from waiting_ - waiting_.erase( - std::find( waiting_.begin(), waiting_.end(), n) ); - throw; + // notifier for main-fiber + detail::main_notifier mn; + n = detail::main_notifier::make_pointer( mn); + + // store this fiber in order to be notified later + waiting_.push_back( n); + + // wait until main-fiber gets notified + while ( ! n->is_ready() ) + { + // run scheduler + detail::scheduler::instance()->run(); + } } } BOOST_ASSERT( ! owner_); diff --git a/test/test_fiber.cpp b/test/test_fiber.cpp index de5cfd60..5734e75a 100644 --- a/test/test_fiber.cpp +++ b/test/test_fiber.cpp @@ -392,19 +392,19 @@ boost::unit_test::test_suite * init_unit_test_suite( int, char* []) boost::unit_test::test_suite * test = BOOST_TEST_SUITE("Boost.Fiber: fiber test suite"); - test->add( BOOST_TEST_CASE( & test_move) ); - test->add( BOOST_TEST_CASE( & test_id) ); - test->add( BOOST_TEST_CASE( & test_priority) ); - test->add( BOOST_TEST_CASE( & test_detach) ); - test->add( BOOST_TEST_CASE( & test_complete) ); - test->add( BOOST_TEST_CASE( & test_replace) ); - test->add( BOOST_TEST_CASE( & test_join_in_thread) ); - test->add( BOOST_TEST_CASE( & test_join_and_run) ); - test->add( BOOST_TEST_CASE( & test_join_in_fiber) ); - test->add( BOOST_TEST_CASE( & test_yield) ); - test->add( BOOST_TEST_CASE( & test_fiber_interrupts_at_interruption_point) ); - test->add( BOOST_TEST_CASE( & test_fiber_no_interrupt_if_interrupts_disabled_at_interruption_point) ); - test->add( BOOST_TEST_CASE( & test_fiber_interrupts_at_join) ); + test->add( BOOST_TEST_CASE( & test_move) ); + test->add( BOOST_TEST_CASE( & test_id) ); + test->add( BOOST_TEST_CASE( & test_priority) ); + test->add( BOOST_TEST_CASE( & test_detach) ); + test->add( BOOST_TEST_CASE( & test_complete) ); + test->add( BOOST_TEST_CASE( & test_replace) ); + test->add( BOOST_TEST_CASE( & test_join_in_thread) ); + test->add( BOOST_TEST_CASE( & test_join_and_run) ); + test->add( BOOST_TEST_CASE( & test_join_in_fiber) ); + test->add( BOOST_TEST_CASE( & test_yield) ); + test->add( BOOST_TEST_CASE( & test_fiber_interrupts_at_interruption_point) ); + test->add( BOOST_TEST_CASE( & test_fiber_no_interrupt_if_interrupts_disabled_at_interruption_point) ); + test->add( BOOST_TEST_CASE( & test_fiber_interrupts_at_join) ); return test; }