mirror of
https://github.com/tearshark/librf.git
synced 2024-10-04 08:50:31 +08:00
支持generator,完成相关范例
This commit is contained in:
parent
7289258a75
commit
8d580dcda4
@ -67,7 +67,7 @@ namespace resumef
|
||||
|
||||
template<typename _PromiseT = void>
|
||||
using coroutine_handle = std::experimental::coroutine_handle<_PromiseT>;
|
||||
template <typename _Ty, typename _Alloc = std::allocator<char>>
|
||||
template <typename _Ty = std::nullptr_t, typename _Alloc = std::allocator<char>>
|
||||
using generator_t = std::experimental::generator<_Ty, _Alloc>;
|
||||
|
||||
enum struct error_code
|
||||
|
@ -166,13 +166,13 @@ namespace experimental {
|
||||
|
||||
void *operator new(size_t _Size)
|
||||
{
|
||||
_Alloc_of_char_type _Al;
|
||||
_Alloc_char _Al;
|
||||
return _Al.allocate(_Size);
|
||||
}
|
||||
|
||||
void operator delete(void *_Ptr, size_t _Size)
|
||||
{
|
||||
_Alloc_of_char_type _Al;
|
||||
_Alloc_char _Al;
|
||||
return _Al.deallocate(static_cast<char *>(_Ptr), _Size);
|
||||
}
|
||||
};
|
||||
@ -228,6 +228,13 @@ namespace experimental {
|
||||
}
|
||||
}
|
||||
|
||||
coroutine_handle<promise_type> detach()
|
||||
{
|
||||
auto t = _Coro;
|
||||
_Coro = nullptr;
|
||||
return t;
|
||||
}
|
||||
|
||||
private:
|
||||
coroutine_handle<promise_type> _Coro = nullptr;
|
||||
};
|
||||
|
@ -13,8 +13,13 @@ namespace resumef
|
||||
RF_API task_base_t();
|
||||
RF_API virtual ~task_base_t();
|
||||
|
||||
virtual state_base_t * get_state() const = 0;
|
||||
|
||||
state_base_t* get_state() const
|
||||
{
|
||||
return _state.get();
|
||||
}
|
||||
protected:
|
||||
counted_ptr<state_base_t> _state;
|
||||
public:
|
||||
task_base_t* _next_node;
|
||||
task_base_t* _prev_node;
|
||||
};
|
||||
@ -31,17 +36,34 @@ namespace resumef
|
||||
using future_type = future_t<value_type>;
|
||||
using state_type = state_t<value_type>;
|
||||
|
||||
counted_ptr<state_type> _state;
|
||||
task_t() = default;
|
||||
task_t(future_type && f)
|
||||
{
|
||||
initialize(std::forward<future_type>(f));
|
||||
}
|
||||
protected:
|
||||
void initialize(future_type&& f)
|
||||
{
|
||||
_state = f._state.get();
|
||||
}
|
||||
};
|
||||
|
||||
template<class _Ty>
|
||||
struct task_t<generator_t<_Ty>> : public task_base_t
|
||||
{
|
||||
using value_type = _Ty;
|
||||
using future_type = generator_t<value_type>;
|
||||
using state_type = state_generator_t;
|
||||
|
||||
task_t() = default;
|
||||
task_t(future_type&& f)
|
||||
: _state(std::move(f._state))
|
||||
{
|
||||
initialize(std::forward<future_type>(f));
|
||||
}
|
||||
|
||||
virtual state_base_t * get_state() const
|
||||
protected:
|
||||
void initialize(future_type&& f)
|
||||
{
|
||||
return _state.get();
|
||||
_state = new state_type(f.detach());
|
||||
}
|
||||
};
|
||||
|
||||
@ -51,25 +73,16 @@ namespace resumef
|
||||
//这个'函数对象'被调用后,返回generator<_Ty>/future_t<_Ty>类型
|
||||
//然后'函数对象'作为异步执行的上下文状态保存起来
|
||||
template<class _Ctx>
|
||||
struct ctx_task_t : public task_base_t
|
||||
struct ctx_task_t : public task_t<typename std::remove_cvref<decltype(std::declval<_Ctx>()())>::type>
|
||||
{
|
||||
using context_type = _Ctx;
|
||||
using future_type = typename std::remove_cvref<decltype(std::declval<_Ctx>()())>::type;
|
||||
using value_type = typename future_type::value_type;
|
||||
using state_type = state_t<value_type>;
|
||||
|
||||
context_type _context;
|
||||
counted_ptr<state_type> _state;
|
||||
|
||||
ctx_task_t(context_type ctx)
|
||||
: _context(std::move(ctx))
|
||||
{
|
||||
_state = _context()._state;
|
||||
}
|
||||
|
||||
virtual state_base_t* get_state() const
|
||||
{
|
||||
return _state.get();
|
||||
this->initialize(_context());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -40,13 +40,13 @@ namespace resumef
|
||||
RF_API void run();
|
||||
//RF_API void break_all();
|
||||
|
||||
template<class _Ty, typename = std::enable_if_t<std::is_callable_v<_Ty> || is_future_v<_Ty>>>
|
||||
template<class _Ty, typename = std::enable_if_t<std::is_callable_v<_Ty> || is_future_v<_Ty> || is_generator_v<_Ty> >>
|
||||
inline void operator + (_Ty && t_)
|
||||
{
|
||||
if constexpr(is_future_v<_Ty>)
|
||||
new_task(new task_t<_Ty>(std::forward<_Ty>(t_)));
|
||||
else
|
||||
if constexpr(std::is_callable_v<_Ty>)
|
||||
new_task(new ctx_task_t<_Ty>(std::forward<_Ty>(t_)));
|
||||
else
|
||||
new_task(new task_t<_Ty>(std::forward<_Ty>(t_)));
|
||||
}
|
||||
|
||||
inline bool empty() const
|
||||
|
@ -15,11 +15,16 @@ namespace resumef
|
||||
{
|
||||
_coro.resume();
|
||||
if (_coro.done())
|
||||
{
|
||||
_coro = nullptr;
|
||||
_scheduler->del_final(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
_scheduler->add_generator(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool state_generator_t::is_ready() const
|
||||
{
|
||||
|
@ -20,8 +20,8 @@ namespace resumef
|
||||
coroutine_handle<> _coro;
|
||||
public:
|
||||
virtual void resume() = 0;
|
||||
virtual bool is_ready() const = 0;
|
||||
virtual bool has_handler() const = 0;
|
||||
virtual bool is_ready() const = 0;
|
||||
|
||||
void set_scheduler(scheduler_t* sch)
|
||||
{
|
||||
@ -35,9 +35,15 @@ namespace resumef
|
||||
|
||||
struct state_generator_t : public state_base_t
|
||||
{
|
||||
public:
|
||||
state_generator_t(coroutine_handle<> handler)
|
||||
{
|
||||
_coro = handler;
|
||||
}
|
||||
|
||||
virtual void resume() override;
|
||||
virtual bool is_ready() const override;
|
||||
virtual bool has_handler() const override;
|
||||
virtual bool is_ready() const override;
|
||||
};
|
||||
|
||||
struct state_future_t : public state_base_t
|
||||
|
@ -46,7 +46,7 @@ void resumable_switch(intptr_t coro, size_t idx)
|
||||
{
|
||||
for (intptr_t i = 0; i < N / coro; ++i)
|
||||
co_yield i;
|
||||
return N / coro;
|
||||
co_return N / coro;
|
||||
};
|
||||
}
|
||||
auto middle = std::chrono::steady_clock::now();
|
||||
|
@ -9,8 +9,7 @@
|
||||
|
||||
using namespace resumef;
|
||||
|
||||
//std::experimental::generator<int>
|
||||
auto test_yield_int() -> std::experimental::generator<int>
|
||||
auto test_yield_int() -> generator_t<int>
|
||||
{
|
||||
std::cout << "1 will yield return" << std::endl;
|
||||
co_yield 1;
|
||||
@ -43,7 +42,7 @@ auto test_yield_void()
|
||||
}
|
||||
*/
|
||||
|
||||
auto test_yield_void() -> std::experimental::generator<std::nullptr_t>
|
||||
auto test_yield_void() -> generator_t<>
|
||||
{
|
||||
std::cout << "block 1 will yield return" << std::endl;
|
||||
co_yield_void;
|
||||
|
@ -30,11 +30,12 @@ int main(int argc, const char* argv[])
|
||||
{
|
||||
//resumable_main_cb();
|
||||
//resumable_main_suspend_always();
|
||||
resumable_main_routine();
|
||||
//resumable_main_yield_return();
|
||||
resumable_main_resumable();
|
||||
//resumable_main_routine();
|
||||
//resumable_main_exception();
|
||||
|
||||
/*
|
||||
resumable_main_resumable();
|
||||
resumable_main_benchmark_mem();
|
||||
if (argc > 1)
|
||||
resumable_main_benchmark_asio_client(atoi(argv[1]));
|
||||
@ -43,10 +44,8 @@ int main(int argc, const char* argv[])
|
||||
|
||||
resumable_main_when_all();
|
||||
resumable_main_multi_thread();
|
||||
resumable_main_yield_return();
|
||||
resumable_main_timer();
|
||||
resumable_main_sleep();
|
||||
resumable_main_resumable();
|
||||
resumable_main_mutex();
|
||||
resumable_main_event();
|
||||
resumable_main_event_timeout();
|
||||
|
@ -243,10 +243,7 @@
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tutorial\test_async_resumable.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\tutorial\test_async_resumable.cpp" />
|
||||
<ClCompile Include="..\tutorial\test_async_routine.cpp" />
|
||||
<ClCompile Include="..\tutorial\test_async_sleep.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
|
Loading…
Reference in New Issue
Block a user