boost/beast/core/detail/stream_base.hpp
//
// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// 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)
//
// Official repository: https://github.com/boostorg/beast
//
#ifndef BOOST_BEAST_CORE_DETAIL_STREAM_BASE_HPP
#define BOOST_BEAST_CORE_DETAIL_STREAM_BASE_HPP
#include <boost/asio/steady_timer.hpp>
#include <boost/assert.hpp>
#include <boost/core/exchange.hpp>
#include <chrono>
#include <cstdint>
#include <utility>
namespace boost {
namespace beast {
namespace detail {
struct any_endpoint
{
template<class Error, class Endpoint>
bool
operator()(
Error const&, Endpoint const&) const noexcept
{
return true;
}
};
struct stream_base
{
using clock_type = std::chrono::steady_clock;
using time_point = typename
std::chrono::steady_clock::time_point;
using tick_type = std::uint64_t;
template<typename Executor>
struct basic_op_state
{
net::basic_waitable_timer<
std::chrono::steady_clock,
net::wait_traits<
std::chrono::steady_clock>,
Executor> timer; // for timing out
tick_type tick = 0; // counts waits
bool pending = false; // if op is pending
bool timeout = false; // if timed out
template<class... Args>
explicit
basic_op_state(Args&&... args)
: timer(std::forward<Args>(args)...)
{
}
};
class pending_guard
{
bool* b_ = nullptr;
bool clear_ = true;
public:
~pending_guard()
{
if(clear_ && b_)
*b_ = false;
}
pending_guard()
: b_(nullptr)
, clear_(true)
{
}
explicit
pending_guard(bool& b)
: b_(&b)
{
// If this assert goes off, it means you are attempting
// to issue two of the same asynchronous I/O operation
// at the same time, without waiting for the first one
// to complete. For example, attempting two simultaneous
// calls to async_read_some. Only one pending call of
// each I/O type (read and write) is permitted.
//
BOOST_ASSERT(! *b_);
*b_ = true;
}
pending_guard(
pending_guard&& other) noexcept
: b_(other.b_)
, clear_(boost::exchange(
other.clear_, false))
{
}
void assign(bool& b)
{
BOOST_ASSERT(!b_);
BOOST_ASSERT(clear_);
b_ = &b;
// If this assert goes off, it means you are attempting
// to issue two of the same asynchronous I/O operation
// at the same time, without waiting for the first one
// to complete. For example, attempting two simultaneous
// calls to async_read_some. Only one pending call of
// each I/O type (read and write) is permitted.
//
BOOST_ASSERT(! *b_);
*b_ = true;
}
void
reset()
{
BOOST_ASSERT(clear_);
if (b_)
*b_ = false;
clear_ = false;
}
};
static time_point never() noexcept
{
return (time_point::max)();
}
static time_point now() noexcept
{
return clock_type::now();
}
static std::size_t constexpr no_limit =
(std::numeric_limits<std::size_t>::max)();
};
} // detail
} // beast
} // boost
#endif