summaryrefslogtreecommitdiff
path: root/boost/fiber/algo/algorithm.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/fiber/algo/algorithm.hpp')
-rw-r--r--boost/fiber/algo/algorithm.hpp114
1 files changed, 114 insertions, 0 deletions
diff --git a/boost/fiber/algo/algorithm.hpp b/boost/fiber/algo/algorithm.hpp
new file mode 100644
index 0000000000..515fc5ed5c
--- /dev/null
+++ b/boost/fiber/algo/algorithm.hpp
@@ -0,0 +1,114 @@
+// 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)
+
+#ifndef BOOST_FIBERS_ALGO_ALGORITHM_H
+#define BOOST_FIBERS_ALGO_ALGORITHM_H
+
+#include <cstddef>
+#include <chrono>
+
+#include <boost/config.hpp>
+#include <boost/assert.hpp>
+
+#include <boost/fiber/properties.hpp>
+#include <boost/fiber/detail/config.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace fibers {
+
+class context;
+
+namespace algo {
+
+struct BOOST_FIBERS_DECL algorithm {
+ virtual ~algorithm() {}
+
+ virtual void awakened( context *) noexcept = 0;
+
+ virtual context * pick_next() noexcept = 0;
+
+ virtual bool has_ready_fibers() const noexcept = 0;
+
+ virtual void suspend_until( std::chrono::steady_clock::time_point const&) noexcept = 0;
+
+ virtual void notify() noexcept = 0;
+};
+
+class BOOST_FIBERS_DECL algorithm_with_properties_base : public algorithm {
+public:
+ // called by fiber_properties::notify() -- don't directly call
+ virtual void property_change_( context * f, fiber_properties * props) noexcept = 0;
+
+protected:
+ static fiber_properties* get_properties( context * f) noexcept;
+ static void set_properties( context * f, fiber_properties * p) noexcept;
+};
+
+template< typename PROPS >
+struct algorithm_with_properties : public algorithm_with_properties_base {
+ typedef algorithm_with_properties_base super;
+
+ // Mark this override 'final': algorithm_with_properties subclasses
+ // must override awakened() with properties parameter instead. Otherwise
+ // you'd have to remember to start every subclass awakened() override
+ // with: algorithm_with_properties<PROPS>::awakened(fb);
+ virtual void awakened( context * f) noexcept override final {
+ fiber_properties * props = super::get_properties( f);
+ if ( nullptr == props) {
+ // TODO: would be great if PROPS could be allocated on the new
+ // fiber's stack somehow
+ props = new_properties( f);
+ // It is not good for new_properties() to return 0.
+ BOOST_ASSERT_MSG(props, "new_properties() must return non-NULL");
+ // new_properties() must return instance of (a subclass of) PROPS
+ BOOST_ASSERT_MSG( dynamic_cast< PROPS * >( props),
+ "new_properties() must return properties class");
+ super::set_properties( f, props);
+ }
+ // Set algo_ again every time this fiber becomes READY. That
+ // handles the case of a fiber migrating to a new thread with a new
+ // algorithm subclass instance.
+ props->set_algorithm( this);
+
+ // Okay, now forward the call to subclass override.
+ awakened( f, properties(f) );
+ }
+
+ // subclasses override this method instead of the original awakened()
+ virtual void awakened( context *, PROPS& ) noexcept = 0;
+
+ // used for all internal calls
+ PROPS & properties( context * f) noexcept {
+ return static_cast< PROPS & >( * super::get_properties( f) );
+ }
+
+ // override this to be notified by PROPS::notify()
+ virtual void property_change( context * f, PROPS & props) noexcept {
+ }
+
+ // implementation for algorithm_with_properties_base method
+ void property_change_( context * f, fiber_properties * props ) noexcept override final {
+ property_change( f, * static_cast< PROPS * >( props) );
+ }
+
+ // Override this to customize instantiation of PROPS, e.g. use a different
+ // allocator. Each PROPS instance is associated with a particular
+ // context.
+ virtual fiber_properties * new_properties( context * f) {
+ return new PROPS( f);
+ }
+};
+
+}}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_FIBERS_ALGO_ALGORITHM_H