#pragma once | #pragma once | ||||
#if ASIO_VERSION >= 101200 | |||||
#if ASIO_VERSION >= 101202 | |||||
#include "asio_task_1.12.2.inl" | |||||
#elif ASIO_VERSION >= 101200 | |||||
#include "asio_task_1.12.0.inl" | #include "asio_task_1.12.0.inl" | ||||
#else | #else | ||||
#include "asio_task_1.10.0.inl" | #include "asio_task_1.10.0.inl" |
#include <memory> | |||||
#include "asio/detail/push_options.hpp" | |||||
namespace asio { | |||||
/** | |||||
* @brief 用于指示asio相关异步函数,返回resumef::future_t<>的类型,从而变成支持 librf 的协程函数。 | |||||
*/ | |||||
template <typename Executor = executor> | |||||
struct rf_task_t | |||||
{ | |||||
ASIO_CONSTEXPR rf_task_t() {} | |||||
}; | |||||
/** | |||||
* @brief 用于指示asio相关异步函数,返回resumef::future_t<>的常量,从而变成支持 librf 的协程函数。 | |||||
*/ | |||||
constexpr rf_task_t<> rf_task; | |||||
namespace librf { | |||||
template <typename Executor, typename _Result> | |||||
struct promise_handler_base | |||||
{ | |||||
public: | |||||
typedef _Result result_type; | |||||
typedef ::resumef::state_t<result_type> state_type; | |||||
promise_handler_base(const rf_task_t<Executor>&) | |||||
: state_(::resumef::state_future_t::_Alloc_state<state_type>(true)) | |||||
{ | |||||
} | |||||
::resumef::counted_ptr<state_type> state_; | |||||
promise_handler_base(promise_handler_base &&) = default; | |||||
promise_handler_base(const promise_handler_base &) = default; | |||||
promise_handler_base & operator = (promise_handler_base &&) = default; | |||||
promise_handler_base & operator = (const promise_handler_base &) = default; | |||||
}; | |||||
template <typename, typename...> | |||||
struct promise_handler; | |||||
template <typename Executor> | |||||
struct promise_handler<Executor, void> : public promise_handler_base<Executor, void> | |||||
{ | |||||
using promise_handler_base<Executor, void>::promise_handler_base; | |||||
void operator()() const | |||||
{ | |||||
this->state_->set_value(); | |||||
} | |||||
}; | |||||
template <typename Executor> | |||||
struct promise_handler<Executor, asio::error_code> : public promise_handler_base<Executor, void> | |||||
{ | |||||
using promise_handler_base<Executor, void>::promise_handler_base; | |||||
void operator()(const asio::error_code& ec) const | |||||
{ | |||||
if (!ec) | |||||
this->state_->set_value(); | |||||
else | |||||
this->state_->set_exception(std::make_exception_ptr(asio::system_error(ec))); | |||||
} | |||||
}; | |||||
template <typename Executor> | |||||
struct promise_handler<Executor, std::exception_ptr> : public promise_handler_base<Executor, void> | |||||
{ | |||||
using promise_handler_base<Executor, void>::promise_handler_base; | |||||
void operator()(std::exception_ptr ex) const | |||||
{ | |||||
if (!ex) | |||||
this->state_->set_value(); | |||||
else | |||||
this->state_->set_exception(ex); | |||||
} | |||||
}; | |||||
template <typename Executor, typename T> | |||||
struct promise_handler<Executor, T> : public promise_handler_base<Executor, T> | |||||
{ | |||||
using promise_handler_base<Executor, T>::promise_handler_base; | |||||
template <typename Arg> | |||||
void operator()(Arg&& arg) const | |||||
{ | |||||
this->state_->set_value(std::forward<Arg>(arg)); | |||||
} | |||||
}; | |||||
template <typename Executor, typename T> | |||||
struct promise_handler<Executor, asio::error_code, T> : public promise_handler_base<Executor, T> | |||||
{ | |||||
using promise_handler_base<Executor, T>::promise_handler_base; | |||||
template <typename Arg> | |||||
void operator()(const asio::error_code& ec, Arg&& arg) const | |||||
{ | |||||
if (!ec) | |||||
this->state_->set_value(std::forward<Arg>(arg)); | |||||
else | |||||
this->state_->set_exception(std::make_exception_ptr(asio::system_error(ec))); | |||||
} | |||||
}; | |||||
template <typename Executor, typename T> | |||||
struct promise_handler<Executor, std::exception_ptr, T> : public promise_handler_base<Executor, T> | |||||
{ | |||||
using promise_handler_base<Executor, T>::promise_handler_base; | |||||
template <typename Arg> | |||||
void operator()(std::exception_ptr ex, Arg&& arg) const | |||||
{ | |||||
if (!ex) | |||||
this->state_->set_value(std::forward<Arg>(arg)); | |||||
else | |||||
this->state_->set_exception(ex); | |||||
} | |||||
}; | |||||
template <typename Executor, typename... Ts> | |||||
struct promise_handler : public promise_handler_base<Executor, std::tuple<Ts...>> | |||||
{ | |||||
using promise_handler_base<Executor, std::tuple<Ts...>>::promise_handler_base; | |||||
template <typename... Args> | |||||
void operator()(Args&&... args) const | |||||
{ | |||||
this->state_->set_value(std::make_tuple(std::forward<Args>(args)...)); | |||||
} | |||||
}; | |||||
template <typename Executor, typename... Ts> | |||||
struct promise_handler<Executor, asio::error_code, Ts...> : public promise_handler_base<Executor, std::tuple<Ts...>> | |||||
{ | |||||
using promise_handler_base<Executor, std::tuple<Ts...>>::promise_handler_base; | |||||
template <typename... Args> | |||||
void operator()(const asio::error_code& ec, Args&&... args) const | |||||
{ | |||||
if (!ec) | |||||
this->state_->set_value(std::make_tuple(std::forward<Args>(args)...)); | |||||
else | |||||
this->state_->set_exception(std::make_exception_ptr(asio::system_error(ec))); | |||||
} | |||||
}; | |||||
template <typename Executor, typename... Ts> | |||||
struct promise_handler<Executor, std::exception_ptr, Ts...> : public promise_handler_base<Executor, std::tuple<Ts...>> | |||||
{ | |||||
using promise_handler_base<Executor, std::tuple<Ts...>>::promise_handler_base; | |||||
template <typename... Args> | |||||
void operator()(std::exception_ptr ex, Args&&... args) const | |||||
{ | |||||
if (!ex) | |||||
this->state_->set_value(std::make_tuple(std::forward<Args>(args)...)); | |||||
else | |||||
this->state_->set_exception(ex); | |||||
} | |||||
}; | |||||
} // namespace librf | |||||
template <typename Executor, typename R, typename... Args> | |||||
class async_result<rf_task_t<Executor>, R(Args...)> | |||||
{ | |||||
public: | |||||
typedef librf::promise_handler<Executor, Args...> completion_handler_type; | |||||
typedef typename completion_handler_type::result_type result_type; | |||||
typedef ::resumef::state_t<result_type> state_type; | |||||
typedef ::resumef::future_t<result_type> return_type; | |||||
async_result(completion_handler_type& hander) | |||||
: state_(hander.state_) | |||||
{} | |||||
return_type get() const noexcept | |||||
{ | |||||
return this->state_; | |||||
} | |||||
private: | |||||
::resumef::counted_ptr<state_type> state_; | |||||
}; | |||||
} // namespace asio | |||||
#include "asio/detail/pop_options.hpp" |
{ | { | ||||
try | try | ||||
{ | { | ||||
bytes_transferred += co_await socket.async_read_some(asio::buffer(buffer.data() + bytes_transferred, buffer.size() - bytes_transferred), rf_task); | |||||
bytes_transferred += co_await socket.async_read_some( | |||||
asio::buffer(buffer.data() + bytes_transferred, buffer.size() - bytes_transferred), rf_task); | |||||
if (bytes_transferred >= buffer.size()) | if (bytes_transferred >= buffer.size()) | ||||
{ | { | ||||
co_await asio::async_write(socket, asio::buffer(buffer, buffer.size()), rf_task); | co_await asio::async_write(socket, asio::buffer(buffer, buffer.size()), rf_task); |
#ifndef RESUMEF_INLINE_STATE | #ifndef RESUMEF_INLINE_STATE | ||||
#if defined(__clang__) || defined(_MSC_VER) | #if defined(__clang__) || defined(_MSC_VER) | ||||
#define RESUMEF_INLINE_STATE 1 | |||||
/* #undef RESUMEF_INLINE_STATE */ | |||||
#else | #else | ||||
#define RESUMEF_INLINE_STATE 1 | |||||
/* #undef RESUMEF_INLINE_STATE */ | |||||
#endif //defined(__clang__) || defined(_MSC_VER) | #endif //defined(__clang__) || defined(_MSC_VER) | ||||
#endif //RESUMEF_INLINE_STATE | #endif //RESUMEF_INLINE_STATE | ||||
<CppLanguageStandard>c++1y</CppLanguageStandard> | <CppLanguageStandard>c++1y</CppLanguageStandard> | ||||
<DisableSpecificWarnings>4834;4505</DisableSpecificWarnings> | <DisableSpecificWarnings>4834;4505</DisableSpecificWarnings> | ||||
<EnableEnhancedInstructionSet>AdvancedVectorExtensions2</EnableEnhancedInstructionSet> | <EnableEnhancedInstructionSet>AdvancedVectorExtensions2</EnableEnhancedInstructionSet> | ||||
<LanguageStandard_C>stdc17</LanguageStandard_C> | |||||
</ClCompile> | </ClCompile> | ||||
<Link> | <Link> | ||||
<SubSystem>Console</SubSystem> | <SubSystem>Console</SubSystem> | ||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> | <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> | ||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> | <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> | ||||
</ClCompile> | </ClCompile> | ||||
<ClCompile Include="..\librf\src\event_v1.cpp" /> | |||||
<ClCompile Include="..\librf\src\event_v2.cpp" /> | <ClCompile Include="..\librf\src\event_v2.cpp" /> | ||||
<ClCompile Include="..\librf\src\mutex_v1.cpp" /> | |||||
<ClCompile Include="..\librf\src\mutex_v2.cpp" /> | <ClCompile Include="..\librf\src\mutex_v2.cpp" /> | ||||
<ClCompile Include="..\librf\src\rf_task.cpp" /> | <ClCompile Include="..\librf\src\rf_task.cpp" /> | ||||
<ClCompile Include="..\librf\src\scheduler.cpp" /> | <ClCompile Include="..\librf\src\scheduler.cpp" /> | ||||
<ClCompile Include="..\librf\src\timer.cpp" /> | <ClCompile Include="..\librf\src\timer.cpp" /> | ||||
<ClCompile Include="..\librf\src\when_v2.cpp" /> | <ClCompile Include="..\librf\src\when_v2.cpp" /> | ||||
<ClCompile Include="..\test_librf.cpp" /> | <ClCompile Include="..\test_librf.cpp" /> | ||||
<ClCompile Include="..\tutorial\gcc_bugs.cpp" /> | |||||
<ClCompile Include="..\tutorial\test_async_cb.cpp" /> | <ClCompile Include="..\tutorial\test_async_cb.cpp" /> | ||||
<ClCompile Include="..\tutorial\test_async_channel.cpp" /> | <ClCompile Include="..\tutorial\test_async_channel.cpp" /> | ||||
<ClCompile Include="..\tutorial\test_async_channel_mult_thread.cpp" /> | <ClCompile Include="..\tutorial\test_async_channel_mult_thread.cpp" /> | ||||
<ClInclude Include="..\librf\librf_macro.h" /> | <ClInclude Include="..\librf\librf_macro.h" /> | ||||
<ClInclude Include="..\librf\src\awaitable.h" /> | <ClInclude Include="..\librf\src\awaitable.h" /> | ||||
<ClInclude Include="..\librf\src\channel.h" /> | <ClInclude Include="..\librf\src\channel.h" /> | ||||
<ClInclude Include="..\librf\src\channel_v1.h" /> | |||||
<ClInclude Include="..\librf\src\channel_v2.h" /> | <ClInclude Include="..\librf\src\channel_v2.h" /> | ||||
<ClInclude Include="..\librf\src\config.h" /> | <ClInclude Include="..\librf\src\config.h" /> | ||||
<ClInclude Include="..\librf\src\counted_ptr.h" /> | <ClInclude Include="..\librf\src\counted_ptr.h" /> | ||||
<ClInclude Include="..\librf\src\current_scheduler.h" /> | <ClInclude Include="..\librf\src\current_scheduler.h" /> | ||||
<ClInclude Include="..\librf\src\def.h" /> | <ClInclude Include="..\librf\src\def.h" /> | ||||
<ClInclude Include="..\librf\src\event.h" /> | <ClInclude Include="..\librf\src\event.h" /> | ||||
<ClInclude Include="..\librf\src\event_v1.h" /> | |||||
<ClInclude Include="..\librf\src\event_v2.h" /> | <ClInclude Include="..\librf\src\event_v2.h" /> | ||||
<ClInclude Include="..\librf\src\future.h" /> | <ClInclude Include="..\librf\src\future.h" /> | ||||
<ClInclude Include="..\librf\src\generator.h" /> | <ClInclude Include="..\librf\src\generator.h" /> | ||||
<ClInclude Include="..\librf\src\intrusive_link_queue.h" /> | <ClInclude Include="..\librf\src\intrusive_link_queue.h" /> | ||||
<ClInclude Include="..\librf\src\mutex_v1.h" /> | |||||
<ClInclude Include="..\librf\src\mutex_v2.h" /> | <ClInclude Include="..\librf\src\mutex_v2.h" /> | ||||
<ClInclude Include="..\librf\src\promise.h" /> | <ClInclude Include="..\librf\src\promise.h" /> | ||||
<ClInclude Include="..\librf\src\mutex.h" /> | <ClInclude Include="..\librf\src\mutex.h" /> | ||||
<ItemGroup> | <ItemGroup> | ||||
<None Include="..\asio\asio_task_1.10.0.inl" /> | <None Include="..\asio\asio_task_1.10.0.inl" /> | ||||
<None Include="..\asio\asio_task_1.12.0.inl" /> | <None Include="..\asio\asio_task_1.12.0.inl" /> | ||||
<None Include="..\asio\asio_task_1.12.2.inl" /> | |||||
<None Include="..\config.h.in" /> | <None Include="..\config.h.in" /> | ||||
<None Include="..\librf\src\channel_v2.inl" /> | <None Include="..\librf\src\channel_v2.inl" /> | ||||
<None Include="..\librf\src\event_v2.inl" /> | <None Include="..\librf\src\event_v2.inl" /> |
<ClCompile Include="..\librf\src\event_v2.cpp"> | <ClCompile Include="..\librf\src\event_v2.cpp"> | ||||
<Filter>librf\src</Filter> | <Filter>librf\src</Filter> | ||||
</ClCompile> | </ClCompile> | ||||
<ClCompile Include="..\librf\src\event_v1.cpp"> | |||||
<Filter>librf\src</Filter> | |||||
</ClCompile> | |||||
<ClCompile Include="..\tutorial\test_async_event_v2.cpp"> | <ClCompile Include="..\tutorial\test_async_event_v2.cpp"> | ||||
<Filter>tutorial</Filter> | <Filter>tutorial</Filter> | ||||
</ClCompile> | </ClCompile> | ||||
<ClCompile Include="..\librf\src\when_v2.cpp"> | <ClCompile Include="..\librf\src\when_v2.cpp"> | ||||
<Filter>librf\src</Filter> | <Filter>librf\src</Filter> | ||||
</ClCompile> | </ClCompile> | ||||
<ClCompile Include="..\librf\src\mutex_v1.cpp"> | |||||
<Filter>librf\src</Filter> | |||||
</ClCompile> | |||||
<ClCompile Include="..\librf\src\mutex_v2.cpp"> | <ClCompile Include="..\librf\src\mutex_v2.cpp"> | ||||
<Filter>librf\src</Filter> | <Filter>librf\src</Filter> | ||||
</ClCompile> | </ClCompile> | ||||
<ClCompile Include="..\test_librf.cpp"> | <ClCompile Include="..\test_librf.cpp"> | ||||
<Filter>Source Files</Filter> | <Filter>Source Files</Filter> | ||||
</ClCompile> | </ClCompile> | ||||
<ClCompile Include="..\tutorial\gcc_bugs.cpp"> | |||||
<Filter>tutorial</Filter> | |||||
</ClCompile> | |||||
<ClCompile Include="..\tutorial\test_async_stop_token.cpp"> | <ClCompile Include="..\tutorial\test_async_stop_token.cpp"> | ||||
<Filter>tutorial</Filter> | <Filter>tutorial</Filter> | ||||
</ClCompile> | </ClCompile> | ||||
<ClInclude Include="..\librf\src\unix\clang_builtin.h"> | <ClInclude Include="..\librf\src\unix\clang_builtin.h"> | ||||
<Filter>librf\src\unix</Filter> | <Filter>librf\src\unix</Filter> | ||||
</ClInclude> | </ClInclude> | ||||
<ClInclude Include="..\librf\src\event_v1.h"> | |||||
<Filter>librf\src</Filter> | |||||
</ClInclude> | |||||
<ClInclude Include="..\librf\src\event_v2.h"> | <ClInclude Include="..\librf\src\event_v2.h"> | ||||
<Filter>librf\src</Filter> | <Filter>librf\src</Filter> | ||||
</ClInclude> | </ClInclude> | ||||
<ClInclude Include="..\tutorial\test_ring_queue.h"> | <ClInclude Include="..\tutorial\test_ring_queue.h"> | ||||
<Filter>tutorial</Filter> | <Filter>tutorial</Filter> | ||||
</ClInclude> | </ClInclude> | ||||
<ClInclude Include="..\librf\src\channel_v1.h"> | |||||
<Filter>librf\src</Filter> | |||||
</ClInclude> | |||||
<ClInclude Include="..\librf\src\channel_v2.h"> | <ClInclude Include="..\librf\src\channel_v2.h"> | ||||
<Filter>librf\src</Filter> | <Filter>librf\src</Filter> | ||||
</ClInclude> | </ClInclude> | ||||
<ClInclude Include="..\librf\src\when_v2.h"> | <ClInclude Include="..\librf\src\when_v2.h"> | ||||
<Filter>librf\src</Filter> | <Filter>librf\src</Filter> | ||||
</ClInclude> | </ClInclude> | ||||
<ClInclude Include="..\librf\src\mutex_v1.h"> | |||||
<Filter>librf\src</Filter> | |||||
</ClInclude> | |||||
<ClInclude Include="..\librf\src\mutex_v2.h"> | <ClInclude Include="..\librf\src\mutex_v2.h"> | ||||
<Filter>librf\src</Filter> | <Filter>librf\src</Filter> | ||||
</ClInclude> | </ClInclude> | ||||
<None Include="..\asio\asio_task_1.12.0.inl"> | <None Include="..\asio\asio_task_1.12.0.inl"> | ||||
<Filter>asio</Filter> | <Filter>asio</Filter> | ||||
</None> | </None> | ||||
<None Include="..\asio\asio_task_1.12.2.inl"> | |||||
<Filter>asio</Filter> | |||||
</None> | |||||
</ItemGroup> | </ItemGroup> | ||||
</Project> | </Project> |