From b3660a3432b7759cb1419ca90f9cfdbe45c0bb15 Mon Sep 17 00:00:00 2001 From: Oliver Kowalke Date: Sun, 20 Sep 2015 11:25:32 +0200 Subject: [PATCH] reorder member variables of context - member hooks must be destroyed before execution_context - otherwise an segementation fault is caused - destruction of execution_context deallocates stack on which the member variables of context are allocated --- include/boost/fiber/context.hpp | 37 ++++++++++++++++++--------------- src/context.cpp | 20 +++++++++--------- 2 files changed, 30 insertions(+), 27 deletions(-) diff --git a/include/boost/fiber/context.hpp b/include/boost/fiber/context.hpp index 0266b720..55ae6b91 100644 --- a/include/boost/fiber/context.hpp +++ b/include/boost/fiber/context.hpp @@ -98,18 +98,6 @@ struct worker_context_t {}; constexpr worker_context_t worker_context = worker_context_t(); class BOOST_FIBERS_DECL context { -public: - detail::ready_hook ready_hook_; - detail::sleep_hook sleep_hook_; - detail::terminated_hook terminated_hook_; - detail::wait_hook wait_hook_; - std::chrono::steady_clock::time_point tp_; - - typedef intrusive::list< - context, - intrusive::function_hook< detail::wait_functor >, - intrusive::constant_time_size< false > > wait_queue_t; - private: enum flag_t { flag_main_context = 1 << 1, @@ -129,6 +117,20 @@ private: #endif scheduler * scheduler_; boost::context::execution_context ctx_; + +public: + detail::ready_hook ready_hook_; + detail::sleep_hook sleep_hook_; + detail::terminated_hook terminated_hook_; + detail::wait_hook wait_hook_; + std::chrono::steady_clock::time_point tp_; + + typedef intrusive::list< + context, + intrusive::function_hook< detail::wait_functor >, + intrusive::constant_time_size< false > > wait_queue_t; + +private: wait_queue_t wait_queue_; detail::spinlock splk_; @@ -207,10 +209,6 @@ public: context( worker_context_t, boost::context::preallocated palloc, StackAlloc salloc, Fn && fn, Args && ... args) : - ready_hook_(), - terminated_hook_(), - wait_hook_(), - tp_( (std::chrono::steady_clock::time_point::max)() ), use_count_( 1), // fiber instance or scheduler owner flags_( flag_worker_context), scheduler_( nullptr), @@ -228,7 +226,12 @@ public: suspend(); BOOST_ASSERT_MSG( false, "fiber already terminated"); }), - wait_queue_() { + ready_hook_(), + terminated_hook_(), + wait_hook_(), + tp_( (std::chrono::steady_clock::time_point::max)() ), + wait_queue_(), + splk_() { } virtual ~context(); diff --git a/src/context.cpp b/src/context.cpp index 57c63b7c..1f0b2e14 100644 --- a/src/context.cpp +++ b/src/context.cpp @@ -52,14 +52,14 @@ context::set_terminated_() noexcept { // main fiber context context::context( main_context_t) : - ready_hook_(), - terminated_hook_(), - wait_hook_(), - tp_( (std::chrono::steady_clock::time_point::max)() ), use_count_( 1), // allocated on main- or thread-stack flags_( flag_main_context), scheduler_( nullptr), ctx_( boost::context::execution_context::current() ), + ready_hook_(), + terminated_hook_(), + wait_hook_(), + tp_( (std::chrono::steady_clock::time_point::max)() ), wait_queue_(), splk_() { } @@ -67,10 +67,6 @@ context::context( main_context_t) : // dispatcher fiber context context::context( dispatcher_context_t, boost::context::preallocated const& palloc, fixedsize_stack const& salloc, scheduler * sched) : - ready_hook_(), - terminated_hook_(), - wait_hook_(), - tp_( (std::chrono::steady_clock::time_point::max)() ), use_count_( 0), // scheduler will own dispatcher context flags_( flag_dispatcher_context), scheduler_( nullptr), @@ -81,6 +77,10 @@ context::context( dispatcher_context_t, boost::context::preallocated const& pall // dispatcher context should never return from scheduler::dispatch() BOOST_ASSERT_MSG( false, "disatcher fiber already terminated"); }), + ready_hook_(), + terminated_hook_(), + wait_hook_(), + tp_( (std::chrono::steady_clock::time_point::max)() ), wait_queue_(), splk_() { } @@ -129,11 +129,11 @@ context::release() noexcept { // notify all waiting fibers wait_queue_t::iterator e = tmp.end(); for ( wait_queue_t::iterator i = tmp.begin(); i != e;) { - context * f = & ( * i); + context * ctx = & ( * i); // remove fiber from wait-queue i = tmp.erase( i); // notify scheduler - scheduler_->set_ready( f); + scheduler_->set_ready( ctx); } }