Browse Source

future支持yield语法,并完成相关范例

tags/v2.9.7
tearshark 4 years ago
parent
commit
2bd318d052

+ 2
- 2
librf/src/promise.inl View File

@@ -82,7 +82,7 @@ namespace resumef
template<class _Ty>
inline void promise_t<_Ty>::yield_value(value_type val)
{
_state->set_value(std::move(val));
_state->promise_yield_value(this, std::move(val));
}

inline void promise_t<void>::return_void()
@@ -92,7 +92,7 @@ namespace resumef

inline void promise_t<void>::yield_value()
{
_state->set_value();
_state->promise_yield_value(this);
}

}

+ 0
- 6
librf/src/rf_task.cpp View File

@@ -5,12 +5,6 @@
namespace resumef
{
task_base_t::task_base_t()
: _next_node(nullptr)
, _prev_node(nullptr)
{
}
task_base_t::~task_base_t()
{
}

+ 1
- 4
librf/src/rf_task.h View File

@@ -10,7 +10,7 @@ namespace resumef
struct task_base_t
{
RF_API task_base_t();
task_base_t() = default;
RF_API virtual ~task_base_t();
state_base_t* get_state() const
@@ -19,9 +19,6 @@ namespace resumef
}
protected:
counted_ptr<state_base_t> _state;
public:
task_base_t* _next_node;
task_base_t* _prev_node;
};
//----------------------------------------------------------------------------------------------

+ 0
- 1
librf/src/scheduler.h View File

@@ -6,7 +6,6 @@
//#include <yvals.h>
#include "rf_task.h"
#include "task_list.h"
#include "utils.h"
#include "timer.h"

+ 4
- 0
librf/src/state.h View File

@@ -114,6 +114,8 @@ namespace resumef
}
auto future_await_resume() -> value_type;
template<class _PromiseT, typename = std::enable_if_t<is_promise_v<_PromiseT>>>
void promise_yield_value(_PromiseT* promise, value_type val);
void set_value(value_type val);
};
@@ -134,6 +136,8 @@ namespace resumef
}
void future_await_resume();
template<class _PromiseT, typename = std::enable_if_t<is_promise_v<_PromiseT>>>
void promise_yield_value(_PromiseT* promise);
void set_value();
};

+ 42
- 3
librf/src/state.inl View File

@@ -3,11 +3,12 @@
namespace resumef
{
template<class _PromiseT, typename _Enable>
inline void state_future_t::promise_initial_suspend(coroutine_handle<_PromiseT> handler)
void state_future_t::promise_initial_suspend(coroutine_handle<_PromiseT> handler)
{
_PromiseT& promise = handler.promise();

state_base_t* parent_state = promise._state.get();
(void)parent_state;
assert(this == parent_state);
assert(this->_scheduler == nullptr);
assert(this->_coro == nullptr);
@@ -19,13 +20,14 @@ namespace resumef
}

template<class _PromiseT, typename _Enable>
inline void state_future_t::promise_final_suspend(coroutine_handle<_PromiseT> handler)
void state_future_t::promise_final_suspend(coroutine_handle<_PromiseT> handler)
{
scoped_lock<lock_type> __guard(this->_mtx);

_PromiseT& promise = handler.promise();

state_base_t* parent_state = promise._state.get();
(void)parent_state;
assert(this == parent_state);

scheduler_t* sch = this->get_scheduler();
@@ -34,7 +36,7 @@ namespace resumef
}

template<class _PromiseT, typename _Enable>
inline void state_future_t::future_await_suspend(coroutine_handle<_PromiseT> handler)
void state_future_t::future_await_suspend(coroutine_handle<_PromiseT> handler)
{
scoped_lock<lock_type> __guard(this->_mtx);

@@ -54,6 +56,43 @@ namespace resumef
sch->add_await(this);
}

template<class _PromiseT, typename _Enable >
void state_t<void>::promise_yield_value(_PromiseT* promise)
{
scoped_lock<lock_type> __guard(this->_mtx);

this->_has_value = true;

coroutine_handle<_PromiseT> handler = coroutine_handle<_PromiseT>::from_promise(*promise);
if (!handler.done())
{
if (this->_coro == nullptr)
this->_coro = handler;
scheduler_t* sch = this->get_scheduler();
if (sch != nullptr)
sch->add_generator(this);
}
}

template<typename _Ty>
template<class _PromiseT, typename _Enable >
void state_t<_Ty>::promise_yield_value(_PromiseT* promise, _Ty val)
{
scoped_lock<lock_type> __guard(this->_mtx);

this->_value = std::move(val);

coroutine_handle<_PromiseT> handler = coroutine_handle<_PromiseT>::from_promise(*promise);
if (!handler.done())
{
if (this->_coro == nullptr)
this->_coro = handler;
scheduler_t* sch = this->get_scheduler();
if (sch != nullptr)
sch->add_generator(this);
}
}

template<typename _Ty>
auto state_t<_Ty>::future_await_resume() -> value_type
{

+ 1
- 1
tutorial/test_async_dynamic_go.cpp View File

@@ -18,7 +18,7 @@ void test_dynamic_go()
{
for (int i = 0; i < M; ++i)
{
go[=]() -> std::experimental::generator<int>
go[=]() -> resumef::generator_t<int>
{
for (int k = 0; k < M; ++k)
{

+ 2
- 1
tutorial/test_async_modern_cb.cpp View File

@@ -308,7 +308,7 @@ struct modern_callback_adapter_t<std_future_t, R(_Result_t...)> : public modern_
struct use_librf_t
{
template<typename _Result_t>
using promise_type = resumef::promise_t<_Result_t>;
using promise_type = resumef::awaitable_t<_Result_t>;

template<typename _Result_t>
using future_type = resumef::future_t<_Result_t>;
@@ -397,6 +397,7 @@ void resumable_main_modern_cb()
try
{
int val = co_await add_async(1, 2, use_librf);
std::cout << val << std::endl;

//muldiv_async函数可能会抛异常,取决于val是否是0
//异常将会带回到本协程里的代码,所以需要try-catch

+ 6
- 3
vs_proj/librf.cpp View File

@@ -28,12 +28,17 @@ extern void resumable_main_benchmark_asio_client(intptr_t nNum);
int main(int argc, const char* argv[])
{
(void)argc;
(void)argv;
//resumable_main_cb();
//resumable_main_modern_cb();
//resumable_main_suspend_always();
//resumable_main_yield_return();
resumable_main_resumable();
//resumable_main_resumable();
//resumable_main_routine();
//resumable_main_exception();
resumable_main_dynamic_go();
/*
resumable_main_benchmark_mem();
@@ -49,9 +54,7 @@ int main(int argc, const char* argv[])
resumable_main_mutex();
resumable_main_event();
resumable_main_event_timeout();
resumable_main_dynamic_go();
resumable_main_channel();
resumable_main_cb();
*/
return 0;

+ 30
- 8
vs_proj/librf.vcxproj View File

@@ -183,22 +183,32 @@
<ClCompile Include="..\benchmark\benchmark_asio_echo.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\benchmark\benchmark_async_mem.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\benchmark\benchmark_channel_passing_next.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\librf\src\event.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\librf\src\mutex.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\librf\src\rf_task.cpp" />
<ClCompile Include="..\librf\src\scheduler.cpp" />
@@ -208,40 +218,48 @@
<ClCompile Include="..\librf\src\when.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\tutorial\test_async_cb.cpp" />
<ClCompile Include="..\tutorial\test_async_channel.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\tutorial\test_async_channel_mult_thread.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\tutorial\test_async_dynamic_go.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\tutorial\test_async_dynamic_go.cpp" />
<ClCompile Include="..\tutorial\test_async_event.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\tutorial\test_async_event_timeout.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\tutorial\test_async_exception.cpp" />
<ClCompile Include="..\tutorial\test_async_modern_cb.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\tutorial\test_async_modern_cb.cpp" />
<ClCompile Include="..\tutorial\test_async_multi_thread.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\tutorial\test_async_mutex.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\tutorial\test_async_resumable.cpp" />
<ClCompile Include="..\tutorial\test_async_routine.cpp" />
@@ -255,10 +273,14 @@
<ClCompile Include="..\tutorial\test_async_timer.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\tutorial\test_async_when_all.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\tutorial\test_async_yield_return.cpp" />
<ClCompile Include="librf.cpp">

Loading…
Cancel
Save