Skip to content

Commit

Permalink
Move async_immediate to a public header.
Browse files Browse the repository at this point in the history
  • Loading branch information
chriskohlhoff committed Jul 7, 2024
1 parent c586e95 commit 25b7372
Show file tree
Hide file tree
Showing 8 changed files with 176 additions and 23 deletions.
1 change: 1 addition & 0 deletions asio/include/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,7 @@ nobase_include_HEADERS = \
asio/handler_continuation_hook.hpp \
asio/high_resolution_timer.hpp \
asio.hpp \
asio/immediate.hpp \
asio/impl/any_completion_executor.ipp \
asio/impl/any_io_executor.ipp \
asio/impl/append.hpp \
Expand Down
1 change: 1 addition & 0 deletions asio/include/asio.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@
#include "asio/generic/stream_protocol.hpp"
#include "asio/handler_continuation_hook.hpp"
#include "asio/high_resolution_timer.hpp"
#include "asio/immediate.hpp"
#include "asio/io_context.hpp"
#include "asio/io_context_strand.hpp"
#include "asio/io_service.hpp"
Expand Down
142 changes: 142 additions & 0 deletions asio/include/asio/immediate.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
//
// immediate.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_IMMEDIATE_HPP
#define ASIO_IMMEDIATE_HPP

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

#include "asio/detail/config.hpp"
#include "asio/associated_immediate_executor.hpp"
#include "asio/async_result.hpp"
#include "asio/dispatch.hpp"

#include "asio/detail/push_options.hpp"

namespace asio {
namespace detail {

template <typename Executor>
class initiate_immediate
{
public:
typedef Executor executor_type;

explicit initiate_immediate(const Executor& ex)
: ex_(ex)
{
}

executor_type get_executor() const noexcept
{
return ex_;
}

template <typename CompletionHandler>
void operator()(CompletionHandler&& handler) const
{
typename associated_immediate_executor<
CompletionHandler, executor_type>::type ex =
(get_associated_immediate_executor)(handler, ex_);
(dispatch)(ex, static_cast<CompletionHandler&&>(handler));
}

private:
Executor ex_;
};

} // namespace detail

/// Launch a trivial asynchronous operation that completes immediately.
/**
* The async_immediate function is intended for use by composed operations,
* which can delegate to this operation in order to implement the correct
* semantics for immediate completion.
*
* @param ex The asynchronous operation's I/O executor.
*
* @param token The completion token.
*
* The completion handler is immediately submitted for execution by calling
* asio::dispatch() on the handler's associated immediate executor.
*
* If the completion handler does not have a customised associated immediate
* executor, then the handler is submitted as if by calling asio::post()
* on the supplied I/O executor.
*
* @par Completion Signature
* @code void() @endcode
*/
template <typename Executor,
ASIO_COMPLETION_TOKEN_FOR(void()) NullaryToken
= default_completion_token_t<Executor>>
inline auto async_immediate(const Executor& ex,
NullaryToken&& token = default_completion_token_t<Executor>(),
constraint_t<
(execution::is_executor<Executor>::value
&& can_require<Executor, execution::blocking_t::never_t>::value)
|| is_executor<Executor>::value
> = 0)
-> decltype(
async_initiate<NullaryToken, void()>(
declval<detail::initiate_immediate<Executor>>(), token))
{
return async_initiate<NullaryToken, void()>(
detail::initiate_immediate<Executor>(ex), token);
}

/// Launch a trivial asynchronous operation that completes immediately.
/**
* The async_immediate function is intended for use by composed operations,
* which can delegate to this operation in order to implement the correct
* semantics for immediate completion.
*
* @param ex The execution context used to obtain the asynchronous operation's
* I/O executor.
*
* @param token The completion token.
*
* The completion handler is immediately submitted for execution by calling
* asio::dispatch() on the handler's associated immediate executor.
*
* If the completion handler does not have a customised associated immediate
* executor, then the handler is submitted as if by calling asio::post()
* on the I/O executor obtained from the supplied execution context.
*
* @par Completion Signature
* @code void() @endcode
*/
template <typename ExecutionContext,
ASIO_COMPLETION_TOKEN_FOR(void()) NullaryToken
= default_completion_token_t<typename ExecutionContext::executor_type>>
inline auto async_immediate(ExecutionContext& ctx,
NullaryToken&& token = default_completion_token_t<
typename ExecutionContext::executor_type>(),
constraint_t<
is_convertible<ExecutionContext&, execution_context&>::value
> = 0)
-> decltype(
async_initiate<NullaryToken, void()>(
declval<detail::initiate_immediate<
typename ExecutionContext::executor_type>>(), token))
{
return async_initiate<NullaryToken, void()>(
detail::initiate_immediate<
typename ExecutionContext::executor_type>(
ctx.get_executor()), token);
}

} // namespace asio

#include "asio/detail/pop_options.hpp"

#endif // ASIO_IMMEDIATE_HPP
1 change: 1 addition & 0 deletions asio/src/Makefile.mgw
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ UNIT_TEST_EXES = \
tests/unit/generic/seq_packet_protocol.exe \
tests/unit/generic/stream_protocol.exe \
tests/unit/high_resolution_timer.exe \
tests/unit/immediate.exe \
tests/unit/io_context.exe \
tests/unit/io_context_strand.exe \
tests/unit/ip/address.exe \
Expand Down
1 change: 1 addition & 0 deletions asio/src/Makefile.msc
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ UNIT_TEST_EXES = \
tests\unit\generic\seq_packet_protocol.exe \
tests\unit\generic\stream_protocol.exe \
tests\unit\high_resolution_timer.exe \
tests\unit\immediate.exe \
tests\unit\io_context.exe \
tests\unit\io_context_strand.exe \
tests\unit\ip\address.exe \
Expand Down
3 changes: 3 additions & 0 deletions asio/src/tests/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ check_PROGRAMS = \
unit/generic/seq_packet_protocol \
unit/generic/stream_protocol \
unit/high_resolution_timer \
unit/immediate \
unit/io_context \
unit/io_context_strand \
unit/ip/address \
Expand Down Expand Up @@ -304,6 +305,7 @@ TESTS = \
unit/executor_work_guard \
unit/file_base \
unit/high_resolution_timer \
unit/immediate \
unit/io_context \
unit/io_context_strand \
unit/ip/address \
Expand Down Expand Up @@ -528,6 +530,7 @@ unit_generic_raw_protocol_SOURCES = unit/generic/raw_protocol.cpp
unit_generic_seq_packet_protocol_SOURCES = unit/generic/seq_packet_protocol.cpp
unit_generic_stream_protocol_SOURCES = unit/generic/stream_protocol.cpp
unit_high_resolution_timer_SOURCES = unit/high_resolution_timer.cpp
unit_immediate_SOURCES = unit/immediate.cpp
unit_io_context_SOURCES = unit/io_context.cpp
unit_io_context_strand_SOURCES = unit/io_context_strand.cpp
unit_ip_address_SOURCES = unit/ip/address.cpp
Expand Down
25 changes: 2 additions & 23 deletions asio/src/tests/unit/bind_immediate_executor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,34 +17,13 @@
#include "asio/bind_immediate_executor.hpp"

#include <functional>
#include "asio/dispatch.hpp"
#include "asio/immediate.hpp"
#include "asio/io_context.hpp"
#include "unit_test.hpp"

using namespace asio;
namespace bindns = std;

struct initiate_immediate
{
template <typename Handler>
void operator()(Handler&& handler, io_context* ctx) const
{
typename associated_immediate_executor<
Handler, io_context::executor_type>::type ex =
get_associated_immediate_executor(handler, ctx->get_executor());
dispatch(ex, static_cast<Handler&&>(handler));
}
};

template <ASIO_COMPLETION_TOKEN_FOR(void()) Token>
ASIO_INITFN_AUTO_RESULT_TYPE_PREFIX(Token, void())
async_immediate(io_context& ctx, Token&& token)
ASIO_INITFN_AUTO_RESULT_TYPE_SUFFIX((
async_initiate<Token, void()>(declval<initiate_immediate>(), token, &ctx)))
{
return async_initiate<Token, void()>(initiate_immediate(), token, &ctx);
}

void increment(int* count)
{
++(*count);
Expand All @@ -70,7 +49,7 @@ void bind_immediate_executor_to_function_object_test()

ASIO_CHECK(count == 1);

async_immediate(ioc1,
async_immediate(ioc1.get_executor(),
bind_immediate_executor(
ioc2.get_executor(),
bind_immediate_executor(
Expand Down
25 changes: 25 additions & 0 deletions asio/src/tests/unit/immediate.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//
// immediate.cpp
// ~~~~~~~~~~~~~
//
// 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)
//

// Disable autolinking for unit tests.
#if !defined(BOOST_ALL_NO_LIB)
#define BOOST_ALL_NO_LIB 1
#endif // !defined(BOOST_ALL_NO_LIB)

// Test that header file is self-contained.
#include "asio/immediate.hpp"

#include "unit_test.hpp"

ASIO_TEST_SUITE
(
"immediate",
ASIO_TEST_CASE(null_test)
)

0 comments on commit 25b7372

Please sign in to comment.