diff --git a/build/Jamfile.v2 b/build/Jamfile.v2 index cd69bfa5..36bc1a89 100644 --- a/build/Jamfile.v2 +++ b/build/Jamfile.v2 @@ -41,6 +41,7 @@ lib boost_fiber future.cpp interruption.cpp mutex.cpp + properties.cpp recursive_mutex.cpp recursive_timed_mutex.cpp round_robin.cpp diff --git a/include/boost/fiber/algorithm.hpp b/include/boost/fiber/algorithm.hpp index 967b885b..2e5f5bda 100644 --- a/include/boost/fiber/algorithm.hpp +++ b/include/boost/fiber/algorithm.hpp @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -57,8 +58,12 @@ public: { // TODO: would be great if PROPS could be allocated on the new // fiber's stack somehow - f->set_properties(new PROPS(f, this)); + f->set_properties(new PROPS(f)); } + // Set sched_algo_ again every time this fiber becomes READY. That + // handles the case of a fiber migrating to a new thread with a new + // sched_algorithm subclass instance. + f->get_properties()->set_sched_algorithm(this); } // used for all internal calls diff --git a/include/boost/fiber/properties.hpp b/include/boost/fiber/properties.hpp index 2d65ce90..e13da8c3 100644 --- a/include/boost/fiber/properties.hpp +++ b/include/boost/fiber/properties.hpp @@ -33,31 +33,36 @@ struct sched_algorithm; class fiber_properties { protected: + // initialized by constructor detail::worker_fiber* fiber_; + // set every time this fiber becomes READY sched_algorithm* sched_algo_; // Inform the relevant sched_algorithm instance that something important // has changed, so it can (presumably) adjust its data structures // accordingly. - void notify() - { - sched_algo_->property_change(fiber_, this); - } + void notify(); public: - // fiber_properties, and by implication every subclass, must accept back - // pointers to its worker_fiber and the associated sched_algorithm*. Any - // specific property setter method, after updating the relevant instance - // variable, can/should call notify(). - fiber_properties(detail::worker_fiber* f, sched_algorithm* algo): + // fiber_properties, and by implication every subclass, must accept a back + // pointer to its worker_fiber. Any specific property setter method, after + // updating the relevant instance variable, can/should call notify(). + fiber_properties(detail::worker_fiber* f): fiber_(f), - sched_algo_(algo) + sched_algo_(0) {} // We need a virtual destructor (hence a vtable) because fiber_properties // is stored polymorphically (as fiber_properties*) in worker_fiber, and // destroyed via that pointer. ~fiber_properties() {} + + // not really intended for public use, but sched_algorithm_with_properties + // must be able to call this + void set_sched_algorithm(sched_algorithm* algo) + { + sched_algo_ = algo; + } }; }} // namespace boost::fibers diff --git a/src/properties.cpp b/src/properties.cpp new file mode 100644 index 00000000..226c7441 --- /dev/null +++ b/src/properties.cpp @@ -0,0 +1,28 @@ +// Copyright Oliver Kowalke 2013. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include +#include "boost/fiber/properties.hpp" +#include "boost/fiber/algorithm.hpp" +#include "boost/fiber/fiber_manager.hpp" + +#ifdef BOOST_HAS_ABI_HEADERS +# include BOOST_ABI_PREFIX +#endif + +namespace boost { +namespace fibers { + +void fiber_properties::notify() +{ + BOOST_ASSERT(sched_algo_); + sched_algo_->property_change(fiber_, this); +} + +}} // boost::fiber + +#ifdef BOOST_HAS_ABI_HEADERS +# include BOOST_ABI_SUFFIX +#endif