├── README.md └── include └── act ├── acceptor.hpp ├── awaiter.hpp ├── connect.hpp ├── detail └── buffer.hpp ├── post.hpp ├── read.hpp ├── resolver.hpp ├── socket.hpp ├── stream.hpp ├── timer.hpp ├── wait.hpp └── write.hpp /README.md: -------------------------------------------------------------------------------- 1 | act 2 | === 3 | 4 | [ASIO](http://www.boost.org/doc/libs/release/doc/html/boost_asio.html) Cooperative Task 5 | 6 | ## Requirements 7 | 8 | - Compiler that implements [N4286](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4286.pdf) 9 | - Or emulation library like [CO2](https://github.com/jamboree/co2) 10 | 11 | ## Dependencies 12 | 13 | - [Boost](http://www.boost.org/) > 1.66.0 14 | 15 | ## Example 16 | 17 | async echo server 18 | ```c++ 19 | task session(asio::ip::tcp::socket sock) 20 | { 21 | try 22 | { 23 | char buf[1024]; 24 | std::cout << "connected: " << sock.remote_endpoint() << std::endl; 25 | for ( ; ; ) 26 | { 27 | act::error_code ec; 28 | auto len = co_await act::read_some(sock, asio::buffer(buf), ec); 29 | if (ec == asio::error::eof) 30 | co_return; 31 | co_await act::write(sock, asio::buffer(buf, len)); 32 | } 33 | } 34 | catch (std::exception& e) 35 | { 36 | std::cout << "error: " << sock.remote_endpoint() << ": " << e.what() << std::endl; 37 | } 38 | } 39 | 40 | task server(asio::io_service& io, unsigned short port) 41 | { 42 | asio::ip::tcp::endpoint endpoint{asio::ip::tcp::v4(), port}; 43 | asio::ip::tcp::acceptor acceptor{io, endpoint}; 44 | asio::ip::tcp::socket sock{io}; 45 | std::cout << "server running at: " << endpoint << std::endl; 46 | for ( ; ; ) 47 | { 48 | co_await act::accept(acceptor, sock); 49 | session(std::move(sock)); 50 | } 51 | } 52 | 53 | int main(int argc, char *argv[]) 54 | { 55 | asio::io_service io; 56 | server(io, std::atoi(argv[1])); 57 | io.run(); 58 | 59 | return EXIT_SUCCESS; 60 | } 61 | ``` 62 | 63 | ## License 64 | 65 | Copyright (c) 2015-2018 Jamboree 66 | 67 | Distributed under the Boost Software License, Version 1.0. (See accompanying 68 | file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 69 | -------------------------------------------------------------------------------- /include/act/acceptor.hpp: -------------------------------------------------------------------------------- 1 | /*////////////////////////////////////////////////////////////////////////////// 2 | Copyright (c) 2015-2017 Jamboree 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 | #ifndef ACT_ACCEPTOR_HPP_INCLUDED 8 | #define ACT_ACCEPTOR_HPP_INCLUDED 9 | 10 | #include 11 | 12 | namespace act 13 | { 14 | template 15 | inline auto accept(Acceptor& acceptor) 16 | { 17 | ACT_RETURN_AWAITER(void, acceptor, accept); 18 | } 19 | 20 | template 21 | inline auto accept(Acceptor& acceptor, error_code& ec) 22 | { 23 | ACT_RETURN_AWAITER_EC(void, acceptor, accept); 24 | } 25 | 26 | template 27 | inline auto accept(Acceptor& acceptor, Socket& socket) 28 | { 29 | ACT_RETURN_AWAITER(void, acceptor, accept, std::ref(socket)); 30 | } 31 | 32 | template 33 | inline auto accept(Acceptor& acceptor, Socket& socket, error_code& ec) 34 | { 35 | ACT_RETURN_AWAITER_EC(void, acceptor, accept, std::ref(socket)); 36 | } 37 | 38 | template 39 | inline auto accept(Acceptor& acceptor, Socket& socket, typename Acceptor::endpoint_type& endpoint) 40 | { 41 | ACT_RETURN_AWAITER(void, acceptor, accept, std::ref(socket), std::ref(endpoint)); 42 | } 43 | 44 | template 45 | inline auto accept(Acceptor& acceptor, Socket& socket, typename Acceptor::endpoint_type& endpoint, error_code& ec) 46 | { 47 | ACT_RETURN_AWAITER_EC(void, acceptor, accept, std::ref(socket), std::ref(endpoint)); 48 | } 49 | } 50 | 51 | #endif -------------------------------------------------------------------------------- /include/act/awaiter.hpp: -------------------------------------------------------------------------------- 1 | /*////////////////////////////////////////////////////////////////////////////// 2 | Copyright (c) 2015-2018 Jamboree 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 | #ifndef ACT_AWAITER_HPP_INCLUDED 8 | #define ACT_AWAITER_HPP_INCLUDED 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | namespace act 15 | { 16 | using error_code = boost::system::error_code; 17 | using system_error = boost::system::system_error; 18 | } 19 | 20 | namespace act { namespace detail 21 | { 22 | template 23 | inline T const& unwrap(T const& val) 24 | { 25 | return val; 26 | } 27 | 28 | template 29 | inline T& unwrap(std::reference_wrapper val) 30 | { 31 | return val; 32 | } 33 | 34 | struct throw_error 35 | { 36 | using error_storage = error_code; 37 | 38 | static void report(error_code const& ec) 39 | { 40 | if (ec) 41 | throw system_error(ec); 42 | } 43 | }; 44 | 45 | struct pass_error 46 | { 47 | using error_storage = error_code&; 48 | 49 | static void report(error_code const&) {} 50 | }; 51 | 52 | template 53 | struct enable_if_valid 54 | { 55 | using type = T; 56 | }; 57 | 58 | template 59 | using enable_if_valid_t = typename enable_if_valid::type; 60 | 61 | template 62 | auto test_coroutine_handle(T t) -> enable_if_valid_t; 63 | std::false_type test_coroutine_handle(...); 64 | 65 | template 66 | struct continuation 67 | { 68 | continuation() noexcept : _ptr() {} 69 | 70 | explicit continuation(CoroHandle handle) noexcept : _ptr(handle) {} 71 | 72 | continuation(continuation&& other) noexcept : _ptr(other._ptr) 73 | { 74 | other._ptr = nullptr; 75 | } 76 | 77 | continuation& operator=(continuation&& other) noexcept 78 | { 79 | if (_ptr) 80 | _ptr.destroy(); 81 | _ptr = other._ptr; 82 | other._ptr = nullptr; 83 | return *this; 84 | } 85 | 86 | ~continuation() 87 | { 88 | if (_ptr) 89 | _ptr.destroy(); 90 | } 91 | 92 | void operator()() noexcept 93 | { 94 | auto coro = _ptr; 95 | _ptr = nullptr; 96 | coro.resume(); 97 | } 98 | 99 | explicit operator bool() const noexcept 100 | { 101 | return _ptr.operator bool(); 102 | } 103 | 104 | private: 105 | CoroHandle _ptr; 106 | }; 107 | 108 | template 109 | struct cont_t 110 | { 111 | template 112 | using wrap = continuation; 113 | }; 114 | 115 | template<> 116 | struct cont_t 117 | { 118 | template 119 | using wrap = T&&; 120 | }; 121 | 122 | template 123 | inline decltype(auto) make_cont(Coro& coro) 124 | { 125 | static constexpr bool is_handle = decltype(test_coroutine_handle(coro))::value; 126 | using cont = typename cont_t::template wrap; 127 | return static_cast(coro); 128 | } 129 | 130 | template 131 | struct awaiter 132 | { 133 | Obj& obj; 134 | F _f; 135 | typename Eh::error_storage _ec; 136 | T _val; 137 | 138 | bool await_ready() const 139 | { 140 | return false; 141 | } 142 | 143 | template 144 | void await_suspend(Coro&& coro) 145 | { 146 | _f(obj, [this, cont = make_cont(coro)](error_code const& ec, T val) mutable 147 | { 148 | _ec = ec; 149 | _val = val; 150 | cont(); 151 | }); 152 | } 153 | 154 | T await_resume() 155 | { 156 | Eh::report(_ec); 157 | return _val; 158 | } 159 | }; 160 | 161 | template 162 | struct awaiter 163 | { 164 | Obj& obj; 165 | F _f; 166 | typename Eh::error_storage _ec; 167 | 168 | bool await_ready() const 169 | { 170 | return false; 171 | } 172 | 173 | template 174 | void await_suspend(Coro&& coro) 175 | { 176 | _f(obj, [&_ec = _ec, cont = make_cont(coro)](error_code const& ec) mutable 177 | { 178 | _ec = ec; 179 | cont(); 180 | }); 181 | } 182 | 183 | void await_resume() 184 | { 185 | Eh::report(_ec); 186 | } 187 | }; 188 | 189 | template 190 | inline auto cancel(Awaiter& a) -> decltype(a.obj.cancel()) 191 | { 192 | a.obj.cancel(); 193 | } 194 | }} 195 | 196 | namespace act 197 | { 198 | template 199 | inline detail::awaiter, detail::throw_error> 200 | make_awaiter(Obj& obj, F&& f) 201 | { 202 | return {obj, std::forward(f)}; 203 | } 204 | 205 | template 206 | inline detail::awaiter, detail::pass_error> 207 | make_awaiter(Obj& obj, F&& f, error_code& ec) 208 | { 209 | return {obj, std::forward(f), ec}; 210 | } 211 | } 212 | 213 | #define ACT_RETURN_AWAITER(R, obj, op, ...) \ 214 | return [&obj](auto&&... args) \ 215 | { \ 216 | return ::act::make_awaiter(obj, [=](auto& obj, auto&& cb) \ 217 | { \ 218 | obj.async_##op(::act::detail::unwrap(args)..., std::move(cb)); \ 219 | }); \ 220 | }(__VA_ARGS__) \ 221 | /***/ 222 | 223 | #define ACT_RETURN_FREE_AWAITER(R, obj, op, ...) \ 224 | return [&obj](auto&&... args) \ 225 | { \ 226 | return ::act::make_awaiter(obj, [=](auto& obj, auto&& cb) \ 227 | { \ 228 | async_##op(obj, ::act::detail::unwrap(args)..., std::move(cb)); \ 229 | }); \ 230 | }(__VA_ARGS__) \ 231 | /***/ 232 | 233 | #define ACT_RETURN_AWAITER_EC(R, obj, op, ...) \ 234 | return [&obj, &ec](auto&&... args) \ 235 | { \ 236 | return ::act::make_awaiter(obj, [=](auto& obj, auto&& cb) \ 237 | { \ 238 | obj.async_##op(::act::detail::unwrap(args)..., std::move(cb)); \ 239 | }, ec); \ 240 | }(__VA_ARGS__) \ 241 | /***/ 242 | 243 | #define ACT_RETURN_FREE_AWAITER_EC(R, obj, op, ...) \ 244 | return [&obj, &ec](auto&&... args) \ 245 | { \ 246 | return ::act::make_awaiter(obj, [=](auto& obj, auto&& cb) \ 247 | { \ 248 | async_##op(obj, ::act::detail::unwrap(args)..., std::move(cb)); \ 249 | }, ec); \ 250 | }(__VA_ARGS__) \ 251 | /***/ 252 | 253 | #endif -------------------------------------------------------------------------------- /include/act/connect.hpp: -------------------------------------------------------------------------------- 1 | /*////////////////////////////////////////////////////////////////////////////// 2 | Copyright (c) 2016-2017 Jamboree 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 | #ifndef ACT_CONNECT_HPP_INCLUDED 8 | #define ACT_CONNECT_HPP_INCLUDED 9 | 10 | #include 11 | #include 12 | 13 | namespace act 14 | { 15 | template 16 | inline auto connect(Socket& socket, Iterator begin, Iterator end) 17 | { 18 | ACT_RETURN_FREE_AWAITER(Iterator, socket, connect, begin, end); 19 | } 20 | 21 | template 22 | inline auto connect(Socket& socket, Iterator begin, Iterator end, error_code& ec) 23 | { 24 | ACT_RETURN_FREE_AWAITER_EC(Iterator, socket, connect, begin, end); 25 | } 26 | 27 | template 28 | inline auto connect(Socket& socket, Iterator begin, Iterator end, ConnectCondition cond) 29 | { 30 | ACT_RETURN_FREE_AWAITER(Iterator, socket, connect, begin, end, cond); 31 | } 32 | 33 | template 34 | inline auto connect(Socket& socket, Iterator begin, Iterator end, ConnectCondition cond, error_code& ec) 35 | { 36 | ACT_RETURN_FREE_AWAITER_EC(Iterator, socket, connect, begin, end, cond); 37 | } 38 | } 39 | 40 | #endif -------------------------------------------------------------------------------- /include/act/detail/buffer.hpp: -------------------------------------------------------------------------------- 1 | /*////////////////////////////////////////////////////////////////////////////// 2 | Copyright (c) 2017 Jamboree 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 | #ifndef ACT_DETAIL_BUFFER_HPP_INCLUDED 8 | #define ACT_DETAIL_BUFFER_HPP_INCLUDED 9 | 10 | #include 11 | #include 12 | 13 | namespace act { namespace detail 14 | { 15 | using ::boost::asio::is_dynamic_buffer; 16 | 17 | // The DynamicBuffer overloads for read/write is flawed. They accept a 18 | // forwarding reference but always make their own copy. We have to workaround 19 | // this by using a ref wrapper. 20 | template 21 | struct dynamic_buffer_ref 22 | { 23 | using const_buffers_type = typename T::const_buffers_type; 24 | using mutable_buffers_type = typename T::mutable_buffers_type; 25 | 26 | T& ref; 27 | 28 | constexpr dynamic_buffer_ref(T& ref) : ref(ref) {} 29 | 30 | std::size_t size() const noexcept 31 | { 32 | return ref.size(); 33 | } 34 | 35 | std::size_t max_size() const noexcept 36 | { 37 | return ref.max_size(); 38 | } 39 | 40 | std::size_t capacity() const noexcept 41 | { 42 | return ref.capacity(); 43 | } 44 | 45 | const_buffers_type data() const noexcept 46 | { 47 | return ref.data(); 48 | } 49 | 50 | mutable_buffers_type prepare(std::size_t n) 51 | { 52 | return ref.prepare(n); 53 | } 54 | 55 | void commit(std::size_t n) 56 | { 57 | return ref.commit(n); 58 | } 59 | 60 | void consume(std::size_t n) 61 | { 62 | return ref.consume(n); 63 | } 64 | }; 65 | 66 | template 67 | struct fwd_buf_impl 68 | { 69 | using type = T&&; 70 | }; 71 | 72 | template 73 | struct fwd_buf_impl::value>> 74 | { 75 | using type = dynamic_buffer_ref; 76 | }; 77 | 78 | template 79 | inline decltype(auto) fwd_buf(T& t) 80 | { 81 | return static_cast::type>(t); 82 | } 83 | }} 84 | 85 | #endif -------------------------------------------------------------------------------- /include/act/post.hpp: -------------------------------------------------------------------------------- 1 | /*////////////////////////////////////////////////////////////////////////////// 2 | Copyright (c) 2015-2017 Jamboree 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 | #ifndef ACT_POST_HPP_INCLUDED 8 | #define ACT_POST_HPP_INCLUDED 9 | 10 | #include 11 | 12 | namespace act { namespace detail 13 | { 14 | template 15 | struct post_awaiter 16 | { 17 | Executor& exe; 18 | 19 | bool await_ready() const 20 | { 21 | return false; 22 | } 23 | 24 | template 25 | void await_suspend(Cb&& cb) 26 | { 27 | post(exe, std::move(cb)); 28 | } 29 | 30 | void await_resume() {} 31 | }; 32 | }} 33 | 34 | namespace act 35 | { 36 | template 37 | inline detail::post_awaiter post(Executor& exe) 38 | { 39 | return {exe}; 40 | } 41 | } 42 | 43 | #endif -------------------------------------------------------------------------------- /include/act/read.hpp: -------------------------------------------------------------------------------- 1 | /*////////////////////////////////////////////////////////////////////////////// 2 | Copyright (c) 2015-2017 Jamboree 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 | #ifndef ACT_READ_HPP_INCLUDED 8 | #define ACT_READ_HPP_INCLUDED 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | namespace act 15 | { 16 | template 17 | inline auto read(AsyncReadStream& stream, Buffer&& buf) 18 | { 19 | ACT_RETURN_FREE_AWAITER(std::size_t, stream, read, detail::fwd_buf(buf)); 20 | } 21 | 22 | template 23 | inline auto read(AsyncReadStream& stream, Buffer&& buf, error_code& ec) 24 | { 25 | ACT_RETURN_FREE_AWAITER_EC(std::size_t, stream, read, detail::fwd_buf(buf)); 26 | } 27 | 28 | template 29 | inline auto read(AsyncReadStream& stream, Buffer&& buf, CompletionCondition condition) 30 | { 31 | ACT_RETURN_FREE_AWAITER(std::size_t, stream, read, detail::fwd_buf(buf), condition); 32 | } 33 | 34 | template 35 | inline auto read(AsyncReadStream& stream, Buffer&& buf, CompletionCondition condition, error_code& ec) 36 | { 37 | ACT_RETURN_FREE_AWAITER_EC(std::size_t, stream, read, detail::fwd_buf(buf), condition); 38 | } 39 | 40 | template 41 | inline auto read_at(AsyncRandomAccessReadDevice& device, std::uint64_t offset, Buffer&& buf) 42 | { 43 | ACT_RETURN_FREE_AWAITER(std::size_t, device, read_at, offset, detail::fwd_buf(buf)); 44 | } 45 | 46 | template 47 | inline auto read_at(AsyncRandomAccessReadDevice& device, std::uint64_t offset, Buffer&& buf, error_code& ec) 48 | { 49 | ACT_RETURN_FREE_AWAITER_EC(std::size_t, device, read_at, offset, detail::fwd_buf(buf)); 50 | } 51 | 52 | template 53 | inline auto read_at(AsyncRandomAccessReadDevice& device, std::uint64_t offset, Buffer&& buf, CompletionCondition condition) 54 | { 55 | ACT_RETURN_FREE_AWAITER(std::size_t, device, read_at, offset, detail::fwd_buf(buf), condition); 56 | } 57 | 58 | template 59 | inline auto read_at(AsyncRandomAccessReadDevice& device, std::uint64_t offset, Buffer&& buf, CompletionCondition condition, error_code& ec) 60 | { 61 | ACT_RETURN_FREE_AWAITER_EC(std::size_t, device, read_at, offset, detail::fwd_buf(buf), condition); 62 | } 63 | 64 | template 65 | inline auto read_until(AsyncReadStream& stream, Buffer&& buf, Delim&& delim) 66 | { 67 | ACT_RETURN_FREE_AWAITER(std::size_t, stream, read_until, detail::fwd_buf(buf), std::forward(delim)); 68 | } 69 | 70 | template 71 | inline auto read_until(AsyncReadStream& stream, Buffer&& buf, Delim&& delim, error_code& ec) 72 | { 73 | ACT_RETURN_FREE_AWAITER_EC(std::size_t, stream, read_until, detail::fwd_buf(buf), std::forward(delim)); 74 | } 75 | } 76 | 77 | #endif -------------------------------------------------------------------------------- /include/act/resolver.hpp: -------------------------------------------------------------------------------- 1 | /*////////////////////////////////////////////////////////////////////////////// 2 | Copyright (c) 2015-2017 Jamboree 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 | #ifndef ACT_RESOLVER_HPP_INCLUDED 8 | #define ACT_RESOLVER_HPP_INCLUDED 9 | 10 | #include 11 | #include 12 | 13 | namespace act 14 | { 15 | using ::boost::asio::string_view; 16 | 17 | template 18 | inline auto resolve(Resolver& resolver, string_view host, string_view service) 19 | { 20 | ACT_RETURN_AWAITER(typename Resolver::results_type, resolver, resolve, host, service); 21 | } 22 | 23 | template 24 | inline auto resolve(Resolver& resolver, string_view host, string_view service, error_code& ec) 25 | { 26 | ACT_RETURN_AWAITER_EC(typename Resolver::results_type, resolver, resolve, host, service); 27 | } 28 | 29 | template 30 | inline auto resolve(Resolver& resolver, string_view host, string_view service, typename Resolver::flags resolve_flags) 31 | { 32 | ACT_RETURN_AWAITER(typename Resolver::results_type, resolver, resolve, host, service, resolve_flags); 33 | } 34 | 35 | template 36 | inline auto resolve(Resolver& resolver, string_view host, string_view service, typename Resolver::flags resolve_flags, error_code& ec) 37 | { 38 | ACT_RETURN_AWAITER_EC(typename Resolver::results_type, resolver, resolve, host, service, resolve_flags); 39 | } 40 | 41 | template 42 | inline auto resolve(Resolver& resolver, typename Resolver::protocol_type const& protocol, string_view host, string_view service) 43 | { 44 | ACT_RETURN_AWAITER(typename Resolver::results_type, resolver, resolve, protocol, host, service); 45 | } 46 | 47 | template 48 | inline auto resolve(Resolver& resolver, typename Resolver::protocol_type const& protocol, string_view host, string_view service, error_code& ec) 49 | { 50 | ACT_RETURN_AWAITER_EC(typename Resolver::results_type, resolver, resolve, protocol, host, service); 51 | } 52 | 53 | template 54 | inline auto resolve(Resolver& resolver, typename Resolver::protocol_type const& protocol, string_view host, string_view service, typename Resolver::flags resolve_flags) 55 | { 56 | ACT_RETURN_AWAITER(typename Resolver::results_type, resolver, resolve, protocol, host, service, resolve_flags); 57 | } 58 | 59 | template 60 | inline auto resolve(Resolver& resolver, typename Resolver::protocol_type const& protocol, string_view host, string_view service, typename Resolver::flags resolve_flags, error_code& ec) 61 | { 62 | ACT_RETURN_AWAITER_EC(typename Resolver::results_type, resolver, resolve, protocol, host, service, resolve_flags); 63 | } 64 | 65 | template 66 | inline auto resolve(Resolver& resolver, typename Resolver::endpoint_type const& endpoint) 67 | { 68 | ACT_RETURN_AWAITER(typename Resolver::results_type, resolver, resolve, endpoint); 69 | } 70 | 71 | template 72 | inline auto resolve(Resolver& resolver, typename Resolver::endpoint_type const& endpoint, error_code& ec) 73 | { 74 | ACT_RETURN_AWAITER_EC(typename Resolver::results_type, resolver, resolve, endpoint); 75 | } 76 | } 77 | 78 | #endif -------------------------------------------------------------------------------- /include/act/socket.hpp: -------------------------------------------------------------------------------- 1 | /*////////////////////////////////////////////////////////////////////////////// 2 | Copyright (c) 2015-2018 Jamboree 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 | #ifndef ACT_SOCKET_HPP_INCLUDED 8 | #define ACT_SOCKET_HPP_INCLUDED 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | namespace act 15 | { 16 | template 17 | inline auto connect(Socket& socket, typename Socket::endpoint_type const& endpoint) 18 | { 19 | ACT_RETURN_AWAITER(void, socket, connect, endpoint); 20 | } 21 | 22 | template 23 | inline auto connect(Socket& socket, typename Socket::endpoint_type const& endpoint, error_code& ec) 24 | { 25 | ACT_RETURN_AWAITER_EC(void, socket, connect, endpoint); 26 | } 27 | 28 | template 29 | inline auto receive(Socket& socket, MutableBufferSequence const& buffers) 30 | { 31 | ACT_RETURN_AWAITER(std::size_t, socket, receive, buffers); 32 | } 33 | 34 | template 35 | inline auto receive(Socket& socket, MutableBufferSequence const& buffers, typename Socket::message_flags flags) 36 | { 37 | ACT_RETURN_AWAITER(std::size_t, socket, receive, buffers, flags); 38 | } 39 | 40 | template 41 | inline auto receive(Socket& socket, MutableBufferSequence const& buffers, typename Socket::message_flags flags, error_code& ec) 42 | { 43 | ACT_RETURN_AWAITER_EC(std::size_t, socket, receive, buffers, flags); 44 | } 45 | 46 | template 47 | inline auto receive_from(Socket& socket, MutableBufferSequence const& buffers, typename Socket::endpoint_type& endpoint) 48 | { 49 | ACT_RETURN_AWAITER(std::size_t, socket, receive_from, buffers, std::ref(endpoint)); 50 | } 51 | 52 | template 53 | inline auto receive_from(Socket& socket, MutableBufferSequence const& buffers, typename Socket::endpoint_type& endpoint, typename Socket::message_flags flags) 54 | { 55 | ACT_RETURN_AWAITER(std::size_t, socket, receive_from, buffers, std::ref(endpoint), flags); 56 | } 57 | 58 | template 59 | inline auto receive_from(Socket& socket, MutableBufferSequence const& buffers, typename Socket::endpoint_type& endpoint, typename Socket::message_flags flags, error_code& ec) 60 | { 61 | ACT_RETURN_AWAITER_EC(std::size_t, socket, receive_from, buffers, std::ref(endpoint), flags); 62 | } 63 | 64 | template 65 | inline auto send(Socket& socket, ConstBufferSequence const& buffers) 66 | { 67 | ACT_RETURN_AWAITER(std::size_t, socket, send, buffers); 68 | } 69 | 70 | template 71 | inline auto send(Socket& socket, ConstBufferSequence const& buffers, typename Socket::message_flags flags) 72 | { 73 | ACT_RETURN_AWAITER(std::size_t, socket, send, buffers, flags); 74 | } 75 | 76 | template 77 | inline auto send(Socket& socket, ConstBufferSequence const& buffers, typename Socket::message_flags flags, error_code& ec) 78 | { 79 | ACT_RETURN_AWAITER_EC(std::size_t, socket, send, buffers, flags); 80 | } 81 | 82 | template 83 | inline auto send_to(Socket& socket, ConstBufferSequence const& buffers, typename Socket::endpoint_type const& endpoint) 84 | { 85 | ACT_RETURN_AWAITER(std::size_t, socket, send_to, buffers, endpoint); 86 | } 87 | 88 | template 89 | inline auto send_to(Socket& socket, ConstBufferSequence const& buffers, typename Socket::endpoint_type const& endpoint, typename Socket::message_flags flags) 90 | { 91 | ACT_RETURN_AWAITER(std::size_t, socket, send_to, buffers, endpoint, flags); 92 | } 93 | 94 | template 95 | inline auto send_to(Socket& socket, ConstBufferSequence const& buffers, typename Socket::endpoint_type const& endpoint, typename Socket::message_flags flags, error_code& ec) 96 | { 97 | ACT_RETURN_AWAITER_EC(std::size_t, socket, send_to, buffers, endpoint, flags); 98 | } 99 | 100 | template 101 | inline auto wait(Socket& socket, typename Socket::wait_type w) 102 | { 103 | ACT_RETURN_AWAITER(std::size_t, socket, wait, w); 104 | } 105 | 106 | template 107 | inline auto wait(Socket& socket, typename Socket::wait_type w, error_code& ec) 108 | { 109 | ACT_RETURN_AWAITER_EC(std::size_t, socket, wait, w); 110 | } 111 | } 112 | 113 | #endif -------------------------------------------------------------------------------- /include/act/stream.hpp: -------------------------------------------------------------------------------- 1 | /*////////////////////////////////////////////////////////////////////////////// 2 | Copyright (c) 2018 Jamboree 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 | #ifndef ACT_STREAM_HPP_INCLUDED 8 | #define ACT_STREAM_HPP_INCLUDED 9 | 10 | #include 11 | #include 12 | 13 | namespace act 14 | { 15 | template 16 | inline auto read_some(Socket& socket, MutableBufferSequence const& buffers) 17 | { 18 | ACT_RETURN_AWAITER(std::size_t, socket, read_some, buffers); 19 | } 20 | 21 | template 22 | inline auto read_some(Socket& socket, MutableBufferSequence const& buffers, error_code& ec) 23 | { 24 | ACT_RETURN_AWAITER_EC(std::size_t, socket, read_some, buffers); 25 | } 26 | 27 | template 28 | inline auto write_some(Socket& socket, ConstBufferSequence const& buffers) 29 | { 30 | ACT_RETURN_AWAITER(std::size_t, socket, write_some, buffers); 31 | } 32 | 33 | template 34 | inline auto write_some(Socket& socket, ConstBufferSequence const& buffers, error_code& ec) 35 | { 36 | ACT_RETURN_AWAITER_EC(std::size_t, socket, write_some, buffers); 37 | } 38 | } 39 | 40 | #endif -------------------------------------------------------------------------------- /include/act/timer.hpp: -------------------------------------------------------------------------------- 1 | /*////////////////////////////////////////////////////////////////////////////// 2 | Copyright (c) 2015-2017 Jamboree 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 | #ifndef ACT_TIMER_HPP_INCLUDED 8 | #define ACT_TIMER_HPP_INCLUDED 9 | 10 | #include 11 | #include 12 | 13 | namespace act 14 | { 15 | template 16 | inline auto sleep_for(Timer& timer, typename Timer::duration const& duration) 17 | { 18 | timer.expires_after(duration); 19 | return wait(timer); 20 | } 21 | 22 | template 23 | inline auto sleep_for(Timer& timer, typename Timer::duration const& duration, error_code& ec) 24 | { 25 | timer.expires_after(duration); 26 | return wait(timer, ec); 27 | } 28 | 29 | template 30 | inline auto sleep_until(Timer& timer, typename Timer::time_point const& time_point) 31 | { 32 | timer.expires_at(time_point); 33 | return wait(timer); 34 | } 35 | 36 | template 37 | inline auto sleep_until(Timer& timer, typename Timer::time_point const& time_point, error_code& ec) 38 | { 39 | timer.expires_at(time_point); 40 | return wait(timer, ec); 41 | } 42 | 43 | namespace detail 44 | { 45 | // Note: if the timer is expired before the task is launched, the task 46 | // may not be cancelled. 47 | template 48 | struct timeout_awaiter 49 | { 50 | Task task; 51 | Timer& timer; 52 | 53 | bool await_ready() const 54 | { 55 | return task.await_ready(); 56 | } 57 | 58 | template 59 | auto await_suspend(Cb&& cb) 60 | { 61 | timer.async_wait([this](error_code const& ec) 62 | { 63 | if (!ec) 64 | cancel(task); 65 | }); 66 | return task.await_suspend(std::forward(cb)); 67 | } 68 | 69 | auto await_resume() -> decltype(task.await_resume()) 70 | { 71 | timer.cancel(); 72 | return task.await_resume(); 73 | } 74 | }; 75 | } 76 | 77 | template 78 | inline detail::timeout_awaiter timeout(Task&& task, Timer& timer, typename Timer::duration const& duration) 79 | { 80 | timer.expires_after(duration); 81 | return {std::forward(task), timer}; 82 | } 83 | } 84 | 85 | #endif -------------------------------------------------------------------------------- /include/act/wait.hpp: -------------------------------------------------------------------------------- 1 | /*////////////////////////////////////////////////////////////////////////////// 2 | Copyright (c) 2017 Jamboree 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 | #ifndef ACT_WAIT_HPP_INCLUDED 8 | #define ACT_WAIT_HPP_INCLUDED 9 | 10 | #include 11 | 12 | namespace act 13 | { 14 | template 15 | inline auto wait(Waitable& waitable) 16 | { 17 | ACT_RETURN_AWAITER(void, waitable, wait); 18 | } 19 | 20 | template 21 | inline auto wait(Waitable& waitable, error_code& ec) 22 | { 23 | ACT_RETURN_AWAITER_EC(void, waitable, wait); 24 | } 25 | } 26 | 27 | #endif -------------------------------------------------------------------------------- /include/act/write.hpp: -------------------------------------------------------------------------------- 1 | /*////////////////////////////////////////////////////////////////////////////// 2 | Copyright (c) 2015-2017 Jamboree 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 | #ifndef ACT_WRITE_HPP_INCLUDED 8 | #define ACT_WRITE_HPP_INCLUDED 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | namespace act 15 | { 16 | template 17 | inline auto write(AsyncWriteStream& stream, Buffer&& buf) 18 | { 19 | ACT_RETURN_FREE_AWAITER(std::size_t, stream, write, detail::fwd_buf(buf)); 20 | } 21 | 22 | template 23 | inline auto write(AsyncWriteStream& stream, Buffer&& buf, error_code& ec) 24 | { 25 | ACT_RETURN_FREE_AWAITER_EC(std::size_t, stream, write, detail::fwd_buf(buf)); 26 | } 27 | 28 | template 29 | inline auto write(AsyncWriteStream& stream, Buffer&& buf, CompletionCondition condition) 30 | { 31 | ACT_RETURN_FREE_AWAITER(std::size_t, stream, write, detail::fwd_buf(buf), condition); 32 | } 33 | 34 | template 35 | inline auto write(AsyncWriteStream& stream, Buffer&& buf, CompletionCondition condition, error_code& ec) 36 | { 37 | ACT_RETURN_FREE_AWAITER_EC(std::size_t, stream, write, detail::fwd_buf(buf), condition); 38 | } 39 | 40 | template 41 | inline auto write_at(AsyncRandomAccessWriteDevice& device, std::uint64_t offset, Buffer&& buf) 42 | { 43 | ACT_RETURN_FREE_AWAITER(std::size_t, device, write_at, offset, detail::fwd_buf(buf)); 44 | } 45 | 46 | template 47 | inline auto write_at(AsyncRandomAccessWriteDevice& device, std::uint64_t offset, Buffer&& buf, error_code& ec) 48 | { 49 | ACT_RETURN_FREE_AWAITER_EC(std::size_t, device, write_at, offset, detail::fwd_buf(buf)); 50 | } 51 | 52 | template 53 | inline auto write_at(AsyncRandomAccessWriteDevice& device, std::uint64_t offset, Buffer&& buf, CompletionCondition condition) 54 | { 55 | ACT_RETURN_FREE_AWAITER(std::size_t, device, write_at, offset, detail::fwd_buf(buf), condition); 56 | } 57 | 58 | template 59 | inline auto write_at(AsyncRandomAccessWriteDevice& device, std::uint64_t offset, Buffer&& buf, CompletionCondition condition, error_code& ec) 60 | { 61 | ACT_RETURN_FREE_AWAITER_EC(std::size_t, device, write_at, offset, detail::fwd_buf(buf), condition); 62 | } 63 | } 64 | 65 | #endif --------------------------------------------------------------------------------