]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/boost/boost/beast/websocket/detail/pausation.hpp
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / boost / boost / beast / websocket / detail / pausation.hpp
index f51ee103274deb0e5e775a311a6d8487c7c058de..e3870b038a0cef20ed2ae3d1741342e3ae0fbb36 100644 (file)
 #ifndef BOOST_BEAST_WEBSOCKET_DETAIL_PAUSATION_HPP
 #define BOOST_BEAST_WEBSOCKET_DETAIL_PAUSATION_HPP
 
-#include <boost/beast/core/handler_ptr.hpp>
+#include <boost/beast/core/detail/allocator.hpp>
 #include <boost/asio/associated_allocator.hpp>
-#include <boost/asio/coroutine.hpp>
 #include <boost/assert.hpp>
-#include <array>
 #include <memory>
-#include <new>
 #include <utility>
 
 namespace boost {
@@ -30,124 +27,59 @@ namespace detail {
 //
 class pausation
 {
-    struct base
+    struct handler
     {
-        base() = default;
-        base(base &&) = delete;
-        base(base const&) = delete;
-        virtual ~base() = default;
-        virtual void operator()() = 0;
+        handler() = default;
+        handler(handler &&) = delete;
+        handler(handler const&) = delete;
+        virtual ~handler() = default;
+        virtual void destroy() = 0;
+        virtual void invoke() = 0;
     };
 
-    template<class F>
-    struct holder : base
+    template<class Handler>
+    class impl : public handler
     {
-        F f;
-
-        holder(holder&&) = default;
-
-        template<class U>
-        explicit
-        holder(U&& u)
-            : f(std::forward<U>(u))
-        {
-        }
-
-        void
-        operator()() override
-        {
-            F f_(std::move(f));
-            this->~holder();
-            // invocation of f_() can
-            // assign a new object to *this.
-            f_();
-        }
-    };
-
-    struct exemplar : boost::asio::coroutine
-    {
-        struct H
-        {
-            void operator()();
-        };
-
-        struct T
-        {
-            using handler_type = H;
-        };
-
-        handler_ptr<T, H> hp;
-
-        void operator()();
-    };
-
-    template<class Op>
-    class saved_op
-    {
-        Op* op_ = nullptr;
+        Handler h_;
 
     public:
-        ~saved_op()
-        {
-            if(op_)
-            {
-                Op op(std::move(*op_));
-                op_->~Op();
-                typename std::allocator_traits<
-                    boost::asio::associated_allocator_t<Op>>::
-                        template rebind_alloc<Op> alloc{
-                            boost::asio::get_associated_allocator(op)};
-                std::allocator_traits<
-                    decltype(alloc)>::deallocate(alloc, op_, 1);
-            }
-        }
-
-        saved_op(saved_op&& other)
-            : op_(other.op_)
+        template<class DeducedHandler>
+        impl(DeducedHandler&& h)
+            : h_(std::forward<DeducedHandler>(h))
         {
-            other.op_ = nullptr;
         }
 
-        saved_op& operator=(saved_op&& other)
-        {
-            BOOST_ASSERT(! op_);
-            op_ = other.op_;
-            other.op_ = 0;
-            return *this;
-        }
-
-        explicit
-        saved_op(Op&& op)
+        void
+        destroy() override
         {
-            typename std::allocator_traits<
-                boost::asio::associated_allocator_t<Op>>::
-                    template rebind_alloc<Op> alloc{
-                        boost::asio::get_associated_allocator(op)};
-            auto const p = std::allocator_traits<
-                decltype(alloc)>::allocate(alloc, 1);
-            op_ = new(p) Op{std::move(op)};
+            Handler h(std::move(h_));
+            typename beast::detail::allocator_traits<
+                boost::asio::associated_allocator_t<
+                    Handler>>::template rebind_alloc<impl> alloc{
+                        boost::asio::get_associated_allocator(h)};
+            beast::detail::allocator_traits<
+                decltype(alloc)>::destroy(alloc, this);
+            beast::detail::allocator_traits<
+                decltype(alloc)>::deallocate(alloc, this, 1);
         }
 
         void
-        operator()()
+        invoke() override
         {
-            BOOST_ASSERT(op_);
-            Op op{std::move(*op_)};
-            typename std::allocator_traits<
-                boost::asio::associated_allocator_t<Op>>::
-                    template rebind_alloc<Op> alloc{
-                        boost::asio::get_associated_allocator(op)};
-            std::allocator_traits<
-                decltype(alloc)>::deallocate(alloc, op_, 1);
-            op_ = nullptr;
-            op();
+            Handler h(std::move(h_));
+            typename beast::detail::allocator_traits<
+                boost::asio::associated_allocator_t<
+                    Handler>>::template rebind_alloc<impl> alloc{
+                        boost::asio::get_associated_allocator(h)};
+            beast::detail::allocator_traits<
+                decltype(alloc)>::destroy(alloc, this);
+            beast::detail::allocator_traits<
+                decltype(alloc)>::deallocate(alloc, this, 1);
+            h();
         }
     };
 
-    using buf_type = char[sizeof(holder<exemplar>)];
-
-    base* base_ = nullptr;
-    alignas(holder<exemplar>) buf_type buf_;
+    handler* h_ = nullptr;
 
 public:
     pausation() = default;
@@ -156,69 +88,70 @@ public:
 
     ~pausation()
     {
-        if(base_)
-            base_->~base();
+        if(h_)
+            h_->destroy();
     }
 
     pausation(pausation&& other)
     {
         boost::ignore_unused(other);
-        BOOST_ASSERT(! other.base_);
+        BOOST_ASSERT(! other.h_);
     }
 
     pausation&
     operator=(pausation&& other)
     {
         boost::ignore_unused(other);
-        BOOST_ASSERT(! base_);
-        BOOST_ASSERT(! other.base_);
+        BOOST_ASSERT(! h_);
+        BOOST_ASSERT(! other.h_);
         return *this;
     }
 
-    template<class F>
-    void
-    emplace(F&& f);
-
-    template<class F>
+    template<class CompletionHandler>
     void
-    save(F&& f);
+    emplace(CompletionHandler&& handler);
 
     explicit
     operator bool() const
     {
-        return base_ != nullptr;
+        return h_ != nullptr;
     }
 
     bool
     maybe_invoke()
     {
-        if(base_)
+        if(h_)
         {
-            auto const basep = base_;
-            base_ = nullptr;
-            (*basep)();
+            auto const h = h_;
+            h_ = nullptr;
+            h->invoke();
             return true;
         }
         return false;
     }
 };
 
-template<class F>
+template<class CompletionHandler>
 void
-pausation::emplace(F&& f)
+pausation::emplace(CompletionHandler&& handler)
 {
-    using type = holder<typename std::decay<F>::type>;
-    static_assert(sizeof(buf_type) >= sizeof(type),
-        "buffer too small");
-    BOOST_ASSERT(! base_);
-    base_ = ::new(buf_) type{std::forward<F>(f)};
-}
-
-template<class F>
-void
-pausation::save(F&& f)
-{
-    emplace(saved_op<F>{std::move(f)});
+    BOOST_ASSERT(! h_);
+    typename beast::detail::allocator_traits<
+        boost::asio::associated_allocator_t<
+            CompletionHandler>>::template rebind_alloc<
+                impl<CompletionHandler>> alloc{
+                    boost::asio::get_associated_allocator(handler)};
+    using A = decltype(alloc);
+    auto const d =
+        [&alloc](impl<CompletionHandler>* p)
+        {
+            beast::detail::allocator_traits<A>::deallocate(alloc, p, 1);
+        };
+    std::unique_ptr<impl<CompletionHandler>, decltype(d)> p{
+        beast::detail::allocator_traits<A>::allocate(alloc, 1), d};
+    beast::detail::allocator_traits<A>::construct(
+        alloc, p.get(), std::forward<CompletionHandler>(handler));
+    h_ = p.release();
 }
 
 } // detail