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.hpp29
1 files changed, 25 insertions, 4 deletions
diff --git a/boost/fiber/algo/algorithm.hpp b/boost/fiber/algo/algorithm.hpp
index 9b846e774b..b22a5923d6 100644
--- a/boost/fiber/algo/algorithm.hpp
+++ b/boost/fiber/algo/algorithm.hpp
@@ -6,11 +6,13 @@
#ifndef BOOST_FIBERS_ALGO_ALGORITHM_H
#define BOOST_FIBERS_ALGO_ALGORITHM_H
-#include <cstddef>
+#include <atomic>
#include <chrono>
+#include <cstddef>
-#include <boost/config.hpp>
#include <boost/assert.hpp>
+#include <boost/config.hpp>
+#include <boost/intrusive_ptr.hpp>
#include <boost/fiber/properties.hpp>
#include <boost/fiber/detail/config.hpp>
@@ -26,7 +28,13 @@ class context;
namespace algo {
-struct BOOST_FIBERS_DECL algorithm {
+class BOOST_FIBERS_DECL algorithm {
+private:
+ std::atomic< std::size_t > use_count_{ 0 };
+
+public:
+ typedef intrusive_ptr< algorithm > ptr_t;
+
virtual ~algorithm() {}
virtual void awakened( context *) noexcept = 0;
@@ -38,6 +46,19 @@ struct BOOST_FIBERS_DECL algorithm {
virtual void suspend_until( std::chrono::steady_clock::time_point const&) noexcept = 0;
virtual void notify() noexcept = 0;
+
+ friend void intrusive_ptr_add_ref( algorithm * algo) noexcept {
+ BOOST_ASSERT( nullptr != algo);
+ algo->use_count_.fetch_add( 1, std::memory_order_relaxed);
+ }
+
+ friend void intrusive_ptr_release( algorithm * algo) noexcept {
+ BOOST_ASSERT( nullptr != algo);
+ if ( 1 == algo->use_count_.fetch_sub( 1, std::memory_order_release) ) {
+ std::atomic_thread_fence( std::memory_order_acquire);
+ delete algo;
+ }
+ }
};
class BOOST_FIBERS_DECL algorithm_with_properties_base : public algorithm {
@@ -60,7 +81,7 @@ struct algorithm_with_properties : public algorithm_with_properties_base {
// with: algorithm_with_properties<PROPS>::awakened(fb);
virtual void awakened( context * ctx) noexcept override final {
fiber_properties * props = super::get_properties( ctx);
- if ( nullptr == props) {
+ if ( BOOST_LIKELY( nullptr == props) ) {
// TODO: would be great if PROPS could be allocated on the new
// fiber's stack somehow
props = new_properties( ctx);