Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Io #8

Draft
wants to merge 43 commits into
base: master
Choose a base branch
from
Draft

Io #8

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
e5da42f
ported boost.buffers
klemens-morgenstern Jun 28, 2023
dfd28e4
added endpoint type
klemens-morgenstern Jun 29, 2023
15185bd
added timers.
klemens-morgenstern Jun 29, 2023
b95d51b
added resolver.
klemens-morgenstern Jun 29, 2023
82d0b01
added duplicate function.
klemens-morgenstern Jun 29, 2023
f8adf15
added signal_set.
klemens-morgenstern Jun 29, 2023
516c9b3
added stream IF.
klemens-morgenstern Jun 29, 2023
096be52
added pipe.
klemens-morgenstern Jun 30, 2023
636476c
added serial_port.
klemens-morgenstern Jun 30, 2023
2ba8988
move-only result workaround.
klemens-morgenstern Jun 30, 2023
a3196df
added networking.
klemens-morgenstern Jun 30, 2023
63a7369
added ssl.
klemens-morgenstern Jun 30, 2023
9b56a02
moved all async_ to source files.
klemens-morgenstern Jun 30, 2023
4841fa9
added file.
klemens-morgenstern Jun 30, 2023
3c833d6
added buffer_register..
klemens-morgenstern Jun 30, 2023
fc5af63
conceptified buffers.
klemens-morgenstern Jun 30, 2023
1571d64
added subspan overloads to all io functions.
klemens-morgenstern Jun 30, 2023
4aeb89a
added read & write.
klemens-morgenstern Jun 30, 2023
f776ce4
added copy.
klemens-morgenstern Jun 30, 2023
f96d893
renamed executor_type to executor for io.
klemens-morgenstern Jul 1, 2023
5e1375f
added process support.
klemens-morgenstern Jul 1, 2023
71e072a
buffer tweaks.
klemens-morgenstern Jul 2, 2023
03cfeb7
removed interrupt_await constant.
klemens-morgenstern Jun 29, 2023
10be212
added result_op to io.
klemens-morgenstern Jun 29, 2023
79cd4a2
added transfer_result
klemens-morgenstern Jul 7, 2023
ed5f354
moved to transfer_result & result_op
klemens-morgenstern Jul 7, 2023
ac8b0fc
minor fixes.
klemens-morgenstern Jul 7, 2023
8bf2936
buffer improvements.
klemens-morgenstern Jul 7, 2023
cd7e6ac
improved read, write & copy algos.
klemens-morgenstern Jul 7, 2023
0f32c6d
dynamic_buffer_view
klemens-morgenstern Jul 4, 2023
0fb458c
algos use dynamic_buffer_view
klemens-morgenstern Jul 7, 2023
4b264a4
include & warning fixes
klemens-morgenstern Jul 22, 2023
8ce5556
remove printf from copy.
klemens-morgenstern Jul 24, 2023
7b0f14f
ported boost.buffers
klemens-morgenstern Jun 28, 2023
c7ebb5d
conceptified buffers.
klemens-morgenstern Jun 30, 2023
6d45d57
added subspan overloads to all io functions.
klemens-morgenstern Jun 30, 2023
a4342f8
buffer tweaks.
klemens-morgenstern Jul 2, 2023
1c0c818
buffer improvements.
klemens-morgenstern Jul 7, 2023
2b2a506
io buffer adjustments
klemens-morgenstern Jul 28, 2023
1244794
rebased.
klemens-morgenstern Aug 1, 2023
ade95f3
added completed_immediately::initiating to io ops.
klemens-morgenstern Aug 4, 2023
4619c05
enabled custom executors in io.
klemens-morgenstern Aug 4, 2023
9d56596
rebase fixes.
klemens-morgenstern Aug 9, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 45 additions & 8 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/doc/index.html

add_custom_target(boost_async_doc DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/doc/index.html)


if(BOOST_ASYNC_IS_ROOT)
#include(CTest)
endif()
Expand Down Expand Up @@ -79,18 +78,56 @@ if (NOT MSVC)
endif()

add_library(boost_async
src/detail/exception.cpp
src/detail/util.cpp
src/error.cpp
src/channel.cpp
src/main.cpp
src/this_thread.cpp
src/thread.cpp)
src/detail/exception.cpp
src/detail/util.cpp
src/error.cpp
src/channel.cpp
src/main.cpp
src/this_thread.cpp
src/thread.cpp
src/io/buffers/circular_buffer.cpp
src/io/buffers/const_buffer_pair.cpp
src/io/buffers/const_buffer_subspan.cpp
src/io/buffers/mutable_buffer_pair.cpp
src/io/buffers/mutable_buffer_subspan.cpp
src/io/detail/duplicate.cpp
src/io/detail/stream.cpp
src/io/acceptor.cpp
src/io/datagram_socket.cpp
src/io/endpoint.cpp
src/io/pipe.cpp
src/io/resolver.cpp
src/io/serial_port.cpp
src/io/signal_set.cpp
src/io/seq_packet_socket.cpp
src/io/socket.cpp
src/io/ssl.cpp
src/io/steady_timer.cpp
src/io/stream_socket.cpp
src/io/system_timer.cpp
src/io/stream_file.cpp
src/io/random_access_file.cpp
src/io/file.cpp
src/io/read.cpp
src/io/read_all.cpp
src/io/read_at.cpp
src/io/read_until.cpp
src/io/popen.cpp
src/io/process.cpp
src/io/buffers/register.cpp
src/io/write.cpp
src/io/write_at.cpp
src/io/detail/random_access_device.cpp
src/io/copy.cpp
src/io/copy_n.cpp
src/io/sleep.cpp)

target_include_directories(boost_async PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")
target_link_libraries(boost_async PUBLIC
Boost::system
Threads::Threads)
target_compile_definitions(boost_async PRIVATE BOOST_ASYNC_SOURCE=1 )
target_compile_definitions(boost_async PUBLIC BOOST_PROCESS_USE_STD_FS=1)

if (BOOST_ASYNC_USE_BOOST_CONTAINER)
target_link_libraries(boost_async PUBLIC Boost::container)
Expand Down
6 changes: 6 additions & 0 deletions doc/reference/io.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[#io]
== async/io.hpp

include::io/timer.adoc[]
include::io/endpoint.adoc[]
include::io/resolver.adoc[]
29 changes: 29 additions & 0 deletions doc/reference/io/buffers/overview.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
////
Copyright (c) 2023 Vinnie Falco ([email protected])

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/CPPAlliance/buffers
////

== Overview

Boost.Buffers is a portable, low-level C++ library which provides
containers and algorithms for describing contiguous buffers of
arbitrary bytes.

Boost.Buffers offers these features:

* Require only C++11
* Works without exceptions
* Fast compilation, few templates
* Does not require Asio

=== Requirements

* Requires Boost and a compiler supporting at least C++20
* Aliases for standard types use their Boost equivalents
* Link to a built static or dynamic Boost library, or use header-only (see below)
* Supports `-fno-exceptions`, detected automatically

132 changes: 132 additions & 0 deletions doc/reference/io/endpoint.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
[#io::endpoint]
=== async/io/endpoint.hpp

The endpoint header provides a simple wrapper around endpoints.

The usage is simple:

[source,cpp]
----
async::io::endpoint domain_socket{async::io::local_stream, "/var/sys/socket"};
async::io::local_endpoint le = get<async::io::local_endpoint>(domain_socket);


async::io::endpoint ip_socket{async::io::tcp, "192.168.0.1", 8080};
async::io::local_endpoint le = get<async::io::ip_socket>(domain_socket);
----

NOTE: `AF_UNSPEC` is treated as an IP that's either ipv6 or ip_v4.

==== Reference


[source,cpp]
----
// a simple type holding the triplet to describe any endpoint
struct protocol_type
{
using family_t = *implementation-defined*;
using type_t = *implementation-defined*;
using protocol_t = *implementation-defined*;

constexpr family_t family() const noexcept {return family_;};
constexpr type_t type() const noexcept {return type_;};
constexpr protocol_t protocol() const noexcept {return protocol_;};

constexpr explicit
protocol_type(family_t family = static_cast<family_t>(0),
type_t type = static_cast<type_t>(0),
protocol_t protocol = static_cast<protocol_t>(0)) noexcept

constexpr protocol_type(const OtherProtocol & op) noexcept;
{}
// asio compatibility
using endpoint = endpoint;
};

// the class holding the endpiont
struct endpoint
{
using storage_type = boost::asio::detail::sockaddr_storage_type;
using addr_type = boost::asio::detail::socket_addr_type;
void resize(std::size_t size);

void * data();
const void * data() const;
std::size_t size();

protocol_type protocol() const;

endpoint() = default;
endpoint(const endpoint & ep);

template<protocol_type::family_t Family,
protocol_type::type_t Type,
protocol_type::protocol_t Protocol,
typename ... Args>
endpoint(static_protocol<Family, Type, Protocol> proto, Args && ... args);

};

// get the type of the endpoint family, see below.
cosnt auto * get_if(const endpoint * ep);
// get the type of the endpoint family, see below. throws `bad_endpoint_access` if a mismatched.
const auto & get(const endpoint & ep);
----

To make it type-safe, the library provides a `static_protocol` template:

[source,cpp]
----
template<protocol_type::family_t Family = static_cast<protocol_type::family_t>(0),
protocol_type::type_t Type = static_cast<protocol_type::type_t>(0),
protocol_type::protocol_t Protocol = static_cast<protocol_type::protocol_t>(0)>
struct static_protocol
{
using family_t = protocol_type::family_t ;
using type_t = protocol_type::type_t ;
using protocol_t = protocol_type::protocol_t;

constexpr family_t family() const noexcept {return Family;};
constexpr type_t type() const noexcept {return Type;};
constexpr protocol_t protocol() const noexcept {return Protocol;};

using endpoint = endpoint;
};
----

These can be used to define a constexpr constant for an endpoint type. The following are provided:

[source,cpp]
----
constexpr static_protocol<AF_UNSPEC, SOCK_STREAM, IPPROTO_IP> ip {};
constexpr static_protocol<AF_INET, SOCK_STREAM, IPPROTO_IP> ip_v4 {};
constexpr static_protocol<AF_INET6, SOCK_STREAM, IPPROTO_IP> ip_v6 {};
constexpr static_protocol<AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP> tcp {};
constexpr static_protocol<AF_INET, SOCK_STREAM, IPPROTO_TCP> tcp_v4{};
constexpr static_protocol<AF_INET6, SOCK_STREAM, IPPROTO_TCP> tcp_v6{};
constexpr static_protocol<AF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP> udp {};
constexpr static_protocol<AF_INET, SOCK_DGRAM, IPPROTO_UDP> udp_v4{};
constexpr static_protocol<AF_INET6, SOCK_DGRAM, IPPROTO_ICMP> udp_v6{};
constexpr static_protocol<AF_UNSPEC, SOCK_DGRAM, IPPROTO_ICMP> icmp {};
constexpr static_protocol<AF_UNIX, SOCK_STREAM> local_stream {};
constexpr static_protocol<AF_UNIX, SOCK_DGRAM> local_datagram {};
constexpr static_protocol<AF_UNIX, SOCK_SEQPACKET> local_seqpacket{};
constexpr static_protocol<AF_UNIX> local_protocol {};
----

To add your own family type you need to implement those two `tag_invoke` functions:

[source,cpp]
----
/// returns the size of the emplaced type.
std::size_t tag_invoke(make_endpoint_tag<YOUR_FAMILY>,
boost::asio::detail::socket_addr_type* base, // memory to in-place new
... /* the arguments you need */);

/// get a pointer to the endpoint type.
const your_endpoint* tag_invoke(get_endpoint_tag<YOUR_FAMILY>,
protocol_type actual,
const endpoint::addr_type * addr);
----

76 changes: 76 additions & 0 deletions doc/reference/io/resolver.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
[#io::resolve]
=== async/io/resolver.hpp

[source,cpp]
----
// a simple type holding the triplet to describe any endpoint
struct protocol_type
{
using family_t = *implementation-defined*;
using type_t = *implementation-defined*;
using protocol_t = *implementation-defined*;

constexpr family_t family() const noexcept {return family_;};
constexpr type_t type() const noexcept {return type_;};
constexpr protocol_t protocol() const noexcept {return protocol_;};

constexpr explicit
protocol_type(family_t family = static_cast<family_t>(0),
type_t type = static_cast<type_t>(0),
protocol_t protocol = static_cast<protocol_t>(0)) noexcept

constexpr protocol_type(const OtherProtocol & op) noexcept;
{}
// asio compatibility
using endpoint = endpoint;
};

// the class holding the endpiont
struct endpoint
{
using storage_type = boost::asio::detail::sockaddr_storage_type;
using addr_type = boost::asio::detail::socket_addr_type;
void resize(std::size_t size);

void * data();
const void * data() const;
std::size_t size();

protocol_type protocol() const;

endpoint() = default;
endpoint(const endpoint & ep);

template<protocol_type::family_t Family,
protocol_type::type_t Type,
protocol_type::protocol_t Protocol,
typename ... Args>
endpoint(static_protocol<Family, Type, Protocol> proto, Args && ... args);

};

// get the type of the endpoint family, see below.
cosnt auto * get_if(const endpoint * ep);
// get the type of the endpoint family, see below. throws `bad_endpoint_access` if a mismatched.
const auto & get(const endpoint & ep);
----

To make it type-safe, the library provides a `static_protocol` template:

[source,cpp]
----

struct resolver
{
using resolve_result = system::result<pmr::vector<endpoint>>;
resolver();
resolver(resolver && ) = delete;

void cancel();

awaitable<result_result> resolve_op_ resolve(core::string_view host, core::string_view service);
};

awaitable<typename resolver::resolve_result> lookup(core::string_view host, core::string_view service);
----

52 changes: 52 additions & 0 deletions doc/reference/io/timer.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
[#io::timer]
=== async/io/steady_timer.hpp, async/io/system_timer.hpp & async/io/sleep.hpp

async.io provides simple timers based on a `std::chrono::steady_clock` and `std::chrono::system_clock`.

The interface between `boost::async::io::steady_timer` and `boost::async::io::system_timer` are equivalent.

[source,cpp]
----
struct steady_timer
{

using wait_result = system::result<void>;

/// The clock type.
typedef std::chrono::steady_clock clock_type;

/// The duration type of the clock.
typedef typename clock_type::duration duration;

/// The time point type of the clock.
typedef typename clock_type::time_point time_point;

steady_timer();
steady_timer(const time_point& expiry_time);
steady_timer(const duration& expiry_duration);

void cancel();

time_point expiry() const;
void reset(const time_point& expiry_time);
void reset(const duration& expiry_time);
bool expired() const;

[[nodiscard]] awaitable<result<void>> wait() { return wait_op_{this}; }
// allow the timer to be directly be awaited
awaitable<result<void>> operator co_await () { return wait(); }
};

awaitable<result<void>> sleep(const steady_timer::time_point& expiry_time);
awaitable<result<void>> sleep(const steady_timer::duration& expiry_duration);
----

==== Example

[source,cpp]
----
async::promise<void> do_delay()
{
co_await sleep(std::chrono::milliseconds(100));
}
----
12 changes: 11 additions & 1 deletion include/boost/async/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,17 @@ namespace pmr = boost::container::pmr;
#if defined(BOOST_ASYNC_USE_STD_PMR)
namespace pmr = std::pmr;
#endif

}

# define BOOST_ASYNC_ERR(ev) ( \
::boost::system::error_code( (ev), [] { \
static constexpr auto loc((BOOST_CURRENT_LOCATION)); \
return &loc; }()))
# define BOOST_ASYNC_RETURN_EC(ev) \
do { \
static constexpr auto loc ## __LINE__((BOOST_CURRENT_LOCATION)); \
return ::boost::system::error_code((ev), &loc ## __LINE__); \
} while(false)


#endif //BOOST_ASYNC_CONFIG_HPP
Loading