Skip to content

Commit

Permalink
Add cancel_at and cancel_after completion token adapters.
Browse files Browse the repository at this point in the history
  • Loading branch information
chriskohlhoff committed Jun 25, 2024
1 parent 3bee286 commit 54282a8
Show file tree
Hide file tree
Showing 26 changed files with 1,469 additions and 108 deletions.
9 changes: 6 additions & 3 deletions asio/include/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ nobase_include_HEADERS = \
asio/buffer.hpp \
asio/buffer_registration.hpp \
asio/buffers_iterator.hpp \
asio/cancel_at.hpp \
asio/cancellation_signal.hpp \
asio/cancellation_state.hpp \
asio/cancellation_type.hpp \
Expand Down Expand Up @@ -75,6 +76,9 @@ nobase_include_HEADERS = \
asio/detail/chrono.hpp \
asio/detail/chrono_time_traits.hpp \
asio/detail/completion_handler.hpp \
asio/detail/completion_message.hpp \
asio/detail/completion_payload.hpp \
asio/detail/completion_payload_handler.hpp \
asio/detail/composed_work.hpp \
asio/detail/concurrency_hint.hpp \
asio/detail/conditionally_enabled_event.hpp \
Expand Down Expand Up @@ -167,6 +171,7 @@ nobase_include_HEADERS = \
asio/detail/initiate_defer.hpp \
asio/detail/initiate_dispatch.hpp \
asio/detail/initiate_post.hpp \
asio/detail/initiation_base.hpp \
asio/detail/io_control.hpp \
asio/detail/io_object_impl.hpp \
asio/detail/io_uring_descriptor_read_at_op.hpp \
Expand Down Expand Up @@ -375,10 +380,7 @@ nobase_include_HEADERS = \
asio/experimental/coro.hpp \
asio/experimental/coro_traits.hpp \
asio/experimental/deferred.hpp \
asio/experimental/detail/channel_handler.hpp \
asio/experimental/detail/channel_message.hpp \
asio/experimental/detail/channel_operation.hpp \
asio/experimental/detail/channel_payload.hpp \
asio/experimental/detail/channel_receive_op.hpp \
asio/experimental/detail/channel_send_functions.hpp \
asio/experimental/detail/channel_send_op.hpp \
Expand Down Expand Up @@ -419,6 +421,7 @@ nobase_include_HEADERS = \
asio/impl/awaitable.hpp \
asio/impl/buffered_read_stream.hpp \
asio/impl/buffered_write_stream.hpp \
asio/impl/cancel_at.ipp \
asio/impl/cancellation_signal.ipp \
asio/impl/co_spawn.hpp \
asio/impl/connect.hpp \
Expand Down
2 changes: 2 additions & 0 deletions asio/include/asio.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@
#include "asio/buffered_write_stream_fwd.hpp"
#include "asio/buffered_write_stream.hpp"
#include "asio/buffers_iterator.hpp"
#include "asio/cancel_after.hpp"
#include "asio/cancel_at.hpp"
#include "asio/cancellation_signal.hpp"
#include "asio/cancellation_state.hpp"
#include "asio/cancellation_type.hpp"
Expand Down
132 changes: 132 additions & 0 deletions asio/include/asio/cancel_after.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
//
// cancel_after.hpp
// ~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2024 Christopher M. Kohlhoff (chris at kohlhoff 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)
//

#ifndef ASIO_CANCEL_AFTER_HPP
#define ASIO_CANCEL_AFTER_HPP

#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)

#include "asio/detail/config.hpp"
#include "asio/cancellation_type.hpp"
#include "asio/detail/chrono.hpp"
#include "asio/detail/type_traits.hpp"
#include "asio/wait_traits.hpp"

#include "asio/detail/push_options.hpp"

namespace asio {

/// A @ref completion_token adapter that cancels an operation after a timeout.
/**
* The cancel_after_t class is used to indicate that an asynchronous operation
* should be cancelled if not complete before the specified duration has
* elapsed.
*/
template <typename CompletionToken, typename Clock,
typename WaitTraits = asio::wait_traits<Clock>>
class cancel_after_t
{
public:
/// Constructor.
template <typename T>
cancel_after_t(T&& completion_token, const typename Clock::duration& timeout,
cancellation_type_t cancel_type = cancellation_type::terminal)
: token_(static_cast<T&&>(completion_token)),
timeout_(timeout),
cancel_type_(cancel_type)
{
}

//private:
CompletionToken token_;
typename Clock::duration timeout_;
cancellation_type_t cancel_type_;
};

/// A function object type that adapts a @ref completion_token to cancel an
/// operation after a timeout.
/**
* May also be used directly as a completion token, in which case it adapts the
* asynchronous operation's default completion token (or asio::deferred
* if no default is available).
*/
template <typename Clock, typename WaitTraits = asio::wait_traits<Clock>>
class partial_cancel_after
{
public:
/// Constructor that specifies the timeout duration and cancellation type.
explicit partial_cancel_after(const typename Clock::duration& timeout,
cancellation_type_t cancel_type = cancellation_type::terminal)
: timeout_(timeout),
cancel_type_(cancel_type)
{
}

/// Adapt a @ref completion_token to specify that the completion handler
/// arguments should be combined into a single tuple argument.
template <typename CompletionToken>
ASIO_NODISCARD inline
constexpr cancel_after_t<decay_t<CompletionToken>, Clock, WaitTraits>
operator()(CompletionToken&& completion_token) const
{
return cancel_after_t<decay_t<CompletionToken>, Clock, WaitTraits>(
static_cast<CompletionToken&&>(completion_token),
timeout_, cancel_type_);
}

//private:
typename Clock::duration timeout_;
cancellation_type_t cancel_type_;
};

/// Create a partial completion token adapter that cancels an operation if not
/// complete before the specified relative timeout has elapsed.
template <typename Rep, typename Period>
ASIO_NODISCARD inline partial_cancel_after<chrono::steady_clock>
cancel_after(const chrono::duration<Rep, Period>& timeout,
cancellation_type_t cancel_type = cancellation_type::terminal)
{
return partial_cancel_after<chrono::steady_clock>(timeout, cancel_type);
}

/// Adapt a @ref completion_token to cancel an operation if not complete before
/// the specified relative timeout has elapsed.
template <typename Rep, typename Period, typename CompletionToken>
ASIO_NODISCARD inline
cancel_after_t<decay_t<CompletionToken>, chrono::steady_clock>
cancel_after(const chrono::duration<Rep, Period>& timeout,
CompletionToken&& completion_token)
{
return cancel_after_t<decay_t<CompletionToken>, chrono::steady_clock>(
static_cast<CompletionToken&&>(completion_token),
timeout, cancellation_type::terminal);
}

/// Adapt a @ref completion_token to cancel an operation if not complete before
/// the specified relative timeout has elapsed.
template <typename Rep, typename Period, typename CompletionToken>
ASIO_NODISCARD inline
cancel_after_t<decay_t<CompletionToken>, chrono::steady_clock>
cancel_after(const chrono::duration<Rep, Period>& timeout,
cancellation_type_t cancel_type, CompletionToken&& completion_token)
{
return cancel_after_t<decay_t<CompletionToken>, chrono::steady_clock>(
static_cast<CompletionToken&&>(completion_token), timeout, cancel_type);
}

} // namespace asio

#include "asio/detail/pop_options.hpp"

#include "asio/impl/cancel_after.hpp"

#endif // ASIO_CANCEL_AFTER_HPP
129 changes: 129 additions & 0 deletions asio/include/asio/cancel_at.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
//
// cancel_at.hpp
// ~~~~~~~~~~~~~
//
// Copyright (c) 2003-2024 Christopher M. Kohlhoff (chris at kohlhoff 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)
//

#ifndef ASIO_CANCEL_AT_HPP
#define ASIO_CANCEL_AT_HPP

#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)

#include "asio/detail/config.hpp"
#include "asio/cancellation_type.hpp"
#include "asio/detail/chrono.hpp"
#include "asio/detail/type_traits.hpp"
#include "asio/wait_traits.hpp"

#include "asio/detail/push_options.hpp"

namespace asio {

/// A @ref completion_token adapter that cancels an operation at a given time.
/**
* The cancel_at_t class is used to indicate that an asynchronous operation
* should be cancelled if not complete at the specified absolute time.
*/
template <typename CompletionToken, typename Clock,
typename WaitTraits = asio::wait_traits<Clock>>
class cancel_at_t
{
public:
/// Constructor.
template <typename T>
cancel_at_t(T&& completion_token, const typename Clock::time_point& expiry,
cancellation_type_t cancel_type = cancellation_type::terminal)
: token_(static_cast<T&&>(completion_token)),
expiry_(expiry),
cancel_type_(cancel_type)
{
}

//private:
CompletionToken token_;
typename Clock::time_point expiry_;
cancellation_type_t cancel_type_;
};

/// A function object type that adapts a @ref completion_token to cancel an
/// operation at a given time.
/**
* May also be used directly as a completion token, in which case it adapts the
* asynchronous operation's default completion token (or asio::deferred
* if no default is available).
*/
template <typename Clock, typename WaitTraits = asio::wait_traits<Clock>>
class partial_cancel_at
{
public:
/// Constructor that specifies the expiry and cancellation type.
explicit partial_cancel_at(const typename Clock::time_point& expiry,
cancellation_type_t cancel_type = cancellation_type::terminal)
: expiry_(expiry),
cancel_type_(cancel_type)
{
}

/// Adapt a @ref completion_token to specify that the completion handler
/// arguments should be combined into a single tuple argument.
template <typename CompletionToken>
ASIO_NODISCARD inline
constexpr cancel_at_t<decay_t<CompletionToken>, Clock, WaitTraits>
operator()(CompletionToken&& completion_token) const
{
return cancel_at_t<decay_t<CompletionToken>, Clock, WaitTraits>(
static_cast<CompletionToken&&>(completion_token),
expiry_, cancel_type_);
}

//private:
typename Clock::time_point expiry_;
cancellation_type_t cancel_type_;
};

/// Create a partial completion token adapter that cancels an operation if not
/// complete by the specified absolute time.
template <typename Clock, typename Duration>
ASIO_NODISCARD inline partial_cancel_at<Clock>
cancel_at(const chrono::time_point<Clock, Duration>& expiry,
cancellation_type_t cancel_type = cancellation_type::terminal)
{
return partial_cancel_at<Clock>(expiry, cancel_type);
}

/// Adapt a @ref completion_token to cancel an operation if not complete by the
/// specified absolute time.
template <typename CompletionToken, typename Clock, typename Duration>
ASIO_NODISCARD inline cancel_at_t<decay_t<CompletionToken>, Clock>
cancel_at(const chrono::time_point<Clock, Duration>& expiry,
CompletionToken&& completion_token)
{
return cancel_at_t<decay_t<CompletionToken>, Clock>(
static_cast<CompletionToken&&>(completion_token),
expiry, cancellation_type::terminal);
}

/// Adapt a @ref completion_token to cancel an operation if not complete by the
/// specified absolute time.
template <typename CompletionToken, typename Clock, typename Duration>
ASIO_NODISCARD inline cancel_at_t<decay_t<CompletionToken>, Clock>
cancel_at(const chrono::time_point<Clock, Duration>& expiry,
cancellation_type_t cancel_type, CompletionToken&& completion_token)
{
return cancel_at_t<decay_t<CompletionToken>, Clock>(
static_cast<CompletionToken&&>(completion_token), expiry, cancel_type);
}

} // namespace asio

#include "asio/detail/pop_options.hpp"

#include "asio/impl/cancel_at.hpp"

#endif // ASIO_CANCEL_AT_HPP
Loading

0 comments on commit 54282a8

Please sign in to comment.