1 //
2 // Copyright (c) 2016-2019 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_CORE_DETAIL_STREAM_BASE_HPP
11 #define BOOST_BEAST_CORE_DETAIL_STREAM_BASE_HPP
12 
13 #include <boost/asio/steady_timer.hpp>
14 #include <boost/assert.hpp>
15 #include <boost/core/exchange.hpp>
16 #include <chrono>
17 #include <cstdint>
18 #include <utility>
19 
20 namespace boost {
21 namespace beast {
22 namespace detail {
23 
24 struct any_endpoint
25 {
26     template<class Error, class Endpoint>
27     bool
operator ()boost::beast::detail::any_endpoint28     operator()(
29         Error const&, Endpoint const&) const noexcept
30     {
31         return true;
32     }
33 };
34 
35 struct stream_base
36 {
37     using clock_type = std::chrono::steady_clock;
38     using time_point = typename
39         std::chrono::steady_clock::time_point;
40     using tick_type = std::uint64_t;
41 
42     struct op_state
43     {
44         net::steady_timer timer;    // for timing out
45         tick_type tick = 0;         // counts waits
46         bool pending = false;       // if op is pending
47         bool timeout = false;       // if timed out
48 
49         template<class... Args>
50         explicit
op_stateboost::beast::detail::stream_base::op_state51         op_state(Args&&... args)
52             : timer(std::forward<Args>(args)...)
53         {
54         }
55     };
56 
57     class pending_guard
58     {
59         bool* b_ = nullptr;
60         bool clear_ = true;
61 
62     public:
~pending_guard()63         ~pending_guard()
64         {
65             if(clear_ && b_)
66                 *b_ = false;
67         }
68 
pending_guard()69         pending_guard()
70         : b_(nullptr)
71         , clear_(true)
72         {
73         }
74 
75         explicit
pending_guard(bool & b)76         pending_guard(bool& b)
77         : b_(&b)
78         {
79             // If this assert goes off, it means you are attempting
80             // to issue two of the same asynchronous I/O operation
81             // at the same time, without waiting for the first one
82             // to complete. For example, attempting two simultaneous
83             // calls to async_read_some. Only one pending call of
84             // each I/O type (read and write) is permitted.
85             //
86             BOOST_ASSERT(! *b_);
87             *b_ = true;
88         }
89 
pending_guard(pending_guard && other)90         pending_guard(
91             pending_guard&& other) noexcept
92             : b_(other.b_)
93             , clear_(boost::exchange(
94                 other.clear_, false))
95         {
96         }
97 
assign(bool & b)98         void assign(bool& b)
99         {
100             BOOST_ASSERT(!b_);
101             BOOST_ASSERT(clear_);
102             b_ = &b;
103 
104             // If this assert goes off, it means you are attempting
105             // to issue two of the same asynchronous I/O operation
106             // at the same time, without waiting for the first one
107             // to complete. For example, attempting two simultaneous
108             // calls to async_read_some. Only one pending call of
109             // each I/O type (read and write) is permitted.
110             //
111             BOOST_ASSERT(! *b_);
112             *b_ = true;
113         }
114 
115         void
reset()116         reset()
117         {
118             BOOST_ASSERT(clear_);
119             if (b_)
120                 *b_ = false;
121             clear_ = false;
122         }
123     };
124 
neverboost::beast::detail::stream_base125     static time_point never() noexcept
126     {
127         return (time_point::max)();
128     }
129 
130     static std::size_t constexpr no_limit =
131         (std::numeric_limits<std::size_t>::max)();
132 };
133 
134 } // detail
135 } // beast
136 } // boost
137 
138 #endif
139