]> git.proxmox.com Git - ceph.git/blame - 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
CommitLineData
b32b8144
FG
1//
2// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
3//
4// Distributed under the Boost Software License, Version 1.0. (See accompanying
5// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6//
7// Official repository: https://github.com/boostorg/beast
8//
9
10#ifndef BOOST_BEAST_WEBSOCKET_DETAIL_PAUSATION_HPP
11#define BOOST_BEAST_WEBSOCKET_DETAIL_PAUSATION_HPP
12
11fdf7f2 13#include <boost/beast/core/detail/allocator.hpp>
b32b8144 14#include <boost/asio/associated_allocator.hpp>
b32b8144 15#include <boost/assert.hpp>
b32b8144 16#include <memory>
b32b8144
FG
17#include <utility>
18
19namespace boost {
20namespace beast {
21namespace websocket {
22namespace detail {
23
24// A container that holds a suspended, asynchronous composed
25// operation. The contained object may be invoked later to
26// resume the operation, or the container may be destroyed.
27//
28class pausation
29{
11fdf7f2 30 struct handler
b32b8144 31 {
11fdf7f2
TL
32 handler() = default;
33 handler(handler &&) = delete;
34 handler(handler const&) = delete;
35 virtual ~handler() = default;
36 virtual void destroy() = 0;
37 virtual void invoke() = 0;
b32b8144
FG
38 };
39
11fdf7f2
TL
40 template<class Handler>
41 class impl : public handler
b32b8144 42 {
11fdf7f2 43 Handler h_;
b32b8144
FG
44
45 public:
11fdf7f2
TL
46 template<class DeducedHandler>
47 impl(DeducedHandler&& h)
48 : h_(std::forward<DeducedHandler>(h))
b32b8144 49 {
b32b8144
FG
50 }
51
11fdf7f2
TL
52 void
53 destroy() override
b32b8144 54 {
11fdf7f2
TL
55 Handler h(std::move(h_));
56 typename beast::detail::allocator_traits<
57 boost::asio::associated_allocator_t<
58 Handler>>::template rebind_alloc<impl> alloc{
59 boost::asio::get_associated_allocator(h)};
60 beast::detail::allocator_traits<
61 decltype(alloc)>::destroy(alloc, this);
62 beast::detail::allocator_traits<
63 decltype(alloc)>::deallocate(alloc, this, 1);
b32b8144
FG
64 }
65
66 void
11fdf7f2 67 invoke() override
b32b8144 68 {
11fdf7f2
TL
69 Handler h(std::move(h_));
70 typename beast::detail::allocator_traits<
71 boost::asio::associated_allocator_t<
72 Handler>>::template rebind_alloc<impl> alloc{
73 boost::asio::get_associated_allocator(h)};
74 beast::detail::allocator_traits<
75 decltype(alloc)>::destroy(alloc, this);
76 beast::detail::allocator_traits<
77 decltype(alloc)>::deallocate(alloc, this, 1);
78 h();
b32b8144
FG
79 }
80 };
81
11fdf7f2 82 handler* h_ = nullptr;
b32b8144
FG
83
84public:
85 pausation() = default;
86 pausation(pausation const&) = delete;
87 pausation& operator=(pausation const&) = delete;
88
89 ~pausation()
90 {
11fdf7f2
TL
91 if(h_)
92 h_->destroy();
b32b8144
FG
93 }
94
95 pausation(pausation&& other)
96 {
97 boost::ignore_unused(other);
11fdf7f2 98 BOOST_ASSERT(! other.h_);
b32b8144
FG
99 }
100
101 pausation&
102 operator=(pausation&& other)
103 {
104 boost::ignore_unused(other);
11fdf7f2
TL
105 BOOST_ASSERT(! h_);
106 BOOST_ASSERT(! other.h_);
b32b8144
FG
107 return *this;
108 }
109
11fdf7f2 110 template<class CompletionHandler>
b32b8144 111 void
11fdf7f2 112 emplace(CompletionHandler&& handler);
b32b8144
FG
113
114 explicit
115 operator bool() const
116 {
11fdf7f2 117 return h_ != nullptr;
b32b8144
FG
118 }
119
120 bool
121 maybe_invoke()
122 {
11fdf7f2 123 if(h_)
b32b8144 124 {
11fdf7f2
TL
125 auto const h = h_;
126 h_ = nullptr;
127 h->invoke();
b32b8144
FG
128 return true;
129 }
130 return false;
131 }
132};
133
11fdf7f2 134template<class CompletionHandler>
b32b8144 135void
11fdf7f2 136pausation::emplace(CompletionHandler&& handler)
b32b8144 137{
11fdf7f2
TL
138 BOOST_ASSERT(! h_);
139 typename beast::detail::allocator_traits<
140 boost::asio::associated_allocator_t<
141 CompletionHandler>>::template rebind_alloc<
142 impl<CompletionHandler>> alloc{
143 boost::asio::get_associated_allocator(handler)};
144 using A = decltype(alloc);
145 auto const d =
146 [&alloc](impl<CompletionHandler>* p)
147 {
148 beast::detail::allocator_traits<A>::deallocate(alloc, p, 1);
149 };
150 std::unique_ptr<impl<CompletionHandler>, decltype(d)> p{
151 beast::detail::allocator_traits<A>::allocate(alloc, 1), d};
152 beast::detail::allocator_traits<A>::construct(
153 alloc, p.get(), std::forward<CompletionHandler>(handler));
154 h_ = p.release();
b32b8144
FG
155}
156
157} // detail
158} // websocket
159} // beast
160} // boost
161
162#endif