Browse Source

恢复新版本下的sleep功能

完善新版本下的部分测试用例
tags/v2.9.7
tearshark 4 years ago
parent
commit
76811ba691

+ 26
- 38
librf/src/awaitable.h View File

namespace resumef namespace resumef
{ {
template<class _Ty> template<class _Ty>
struct awaitable_t
struct awaitable_impl_t
{ {
using value_type = _Ty; using value_type = _Ty;
using state_type = state_t<value_type>; using state_type = state_t<value_type>;
using future_type = future_t<value_type>; using future_type = future_t<value_type>;
using lock_type = typename state_type::lock_type; using lock_type = typename state_type::lock_type;


private:
mutable counted_ptr<state_type> _state = make_counted<state_type>(true);
public:
awaitable_t() {}
awaitable_t(const awaitable_t&) = default;
awaitable_t(awaitable_t&&) = default;
awaitable_impl_t() {}
awaitable_impl_t(const awaitable_impl_t&) = default;
awaitable_impl_t(awaitable_impl_t&&) = default;


awaitable_t& operator = (const awaitable_t&) = default;
awaitable_t& operator = (awaitable_t&&) = default;
awaitable_impl_t& operator = (const awaitable_impl_t&) = default;
awaitable_impl_t& operator = (awaitable_impl_t&&) = default;


void set_value(value_type value) const
void set_exception(std::exception_ptr e) const
{ {
_state->set_value(std::move(value));
_state->set_exception(std::move(e));
_state = nullptr; _state = nullptr;
} }


void set_exception(std::exception_ptr e)
template<class _Exp>
void throw_exception(_Exp e) const
{ {
_state->set_exception(std::move(e));
_state = nullptr;
set_exception(std::make_exception_ptr(std::move(e)));
} }


future_type get_future() future_type get_future()
{ {
return future_type{ _state }; return future_type{ _state };
} }
protected:
mutable counted_ptr<state_type> _state = make_counted<state_type>(true);
}; };


template<>
struct awaitable_t<void>
template<class _Ty>
struct awaitable_t : public awaitable_impl_t<_Ty>
{ {
using value_type = void;
using state_type = state_t<void>;
using future_type = future_t<void>;
using lock_type = typename state_type::lock_type;

mutable counted_ptr<state_type> _state = make_counted<state_type>(true);
using awaitable_impl_t::awaitable_impl_t;


awaitable_t() {}
awaitable_t(const awaitable_t&) = default;
awaitable_t(awaitable_t&&) = default;

awaitable_t& operator = (const awaitable_t&) = default;
awaitable_t& operator = (awaitable_t&&) = default;

void set_value() const
void set_value(value_type value) const
{ {
_state->set_value();
_state->set_value(std::move(value));
_state = nullptr; _state = nullptr;
} }
};


void set_exception(std::exception_ptr e)
{
_state->set_exception(std::move(e));
_state = nullptr;
}
template<>
struct awaitable_t<void> : public awaitable_impl_t<void>
{
using awaitable_impl_t::awaitable_impl_t;


future_type get_future()
void set_value() const
{ {
return future_type{ _state };
_state->set_value();
_state = nullptr;
} }
}; };
} }

+ 2
- 1
librf/src/def.h View File

template<class _Ty = void> template<class _Ty = void>
struct future_t; struct future_t;
using future_vt = future_t<>;
using future_vt [[deprecated]] = future_t<>;
template<class _Ty = void> template<class _Ty = void>
struct promise_t; struct promise_t;

+ 5
- 4
librf/src/sleep.cpp View File

#include "scheduler.h" #include "scheduler.h"
#include "awaitable.h"
#include "sleep.h" #include "sleep.h"
namespace resumef namespace resumef
{ {
future_t<> sleep_until_(const std::chrono::system_clock::time_point& tp_, scheduler_t& scheduler_) future_t<> sleep_until_(const std::chrono::system_clock::time_point& tp_, scheduler_t& scheduler_)
{ {
promise_vt awaitable;
awaitable_t<> awaitable;
(void)scheduler_.timer()->add(tp_, (void)scheduler_.timer()->add(tp_,
[st = awaitable._state](bool cancellation_requested)
[awaitable](bool cancellation_requested)
{ {
if (cancellation_requested) if (cancellation_requested)
st->throw_exception(timer_canceled_exception{ error_code::timer_canceled });
awaitable.throw_exception(timer_canceled_exception{ error_code::timer_canceled });
else else
st->set_value();
awaitable.set_value();
}); });
return awaitable.get_future(); return awaitable.get_future();

+ 1
- 2
tutorial/test_async_cb.cpp View File

using namespace std::chrono; using namespace std::chrono;
std::thread([val, cb = std::forward<_Ctype>(cb)] std::thread([val, cb = std::forward<_Ctype>(cb)]
{ {
//std::this_thread::sleep_for(500ms);
std::this_thread::sleep_for(2s);
std::this_thread::sleep_for(500ms);
cb(val * val); cb(val * val);
}).detach(); }).detach();
} }

+ 8
- 8
tutorial/test_async_exception.cpp View File

//请打开结构化异常(/EHa) //请打开结构化异常(/EHa)
auto async_signal_exception(const intptr_t dividend) auto async_signal_exception(const intptr_t dividend)
{ {
promise_t<int64_t> awaitable;
awaitable_t<int64_t> awaitable;
std::thread([dividend, st = awaitable._state]
std::thread([dividend, awaitable]
{ {
std::this_thread::sleep_for(std::chrono::milliseconds(50)); std::this_thread::sleep_for(std::chrono::milliseconds(50));
try try
//也可以注释掉这个判断,使用结构化异常。但就获得不了具体描述信息了 //也可以注释掉这个判断,使用结构化异常。但就获得不了具体描述信息了
if (dividend == 0) if (dividend == 0)
throw std::logic_error("divided by zero"); throw std::logic_error("divided by zero");
st->set_value(10000 / dividend);
awaitable.set_value(10000 / dividend);
} }
catch (...) catch (...)
{ {
st->set_exception(std::current_exception());
awaitable.set_exception(std::current_exception());
} }
}).detach(); }).detach();
auto async_signal_exception2(const intptr_t dividend) auto async_signal_exception2(const intptr_t dividend)
{ {
promise_t<int64_t> awaitable;
awaitable_t<int64_t> awaitable;
std::thread([dividend, st = awaitable._state]
std::thread([dividend, awaitable]
{ {
std::this_thread::sleep_for(std::chrono::milliseconds(50)); std::this_thread::sleep_for(std::chrono::milliseconds(50));
if (dividend == 0) if (dividend == 0)
st->throw_exception(std::logic_error("divided by zero"));
awaitable.throw_exception(std::logic_error("divided by zero"));
else else
st->set_value(10000 / dividend);
awaitable.set_value(10000 / dividend);
}).detach(); }).detach();
return awaitable.get_future(); return awaitable.get_future();

+ 1
- 1
tutorial/test_async_multi_thread.cpp View File

return awaitable.get_future(); return awaitable.get_future();
} }
future_vt heavy_computing_sequential(int64_t val)
future_t<> heavy_computing_sequential(int64_t val)
{ {
for(size_t i = 0; i < 3; ++i) for(size_t i = 0; i < 3; ++i)
{ {

+ 2
- 2
tutorial/test_async_mutex.cpp View File

mutex_t g_lock; mutex_t g_lock;
std::deque<size_t> g_queue; std::deque<size_t> g_queue;
future_vt test_mutex_pop(size_t idx)
future_t<> test_mutex_pop(size_t idx)
{ {
using namespace std::chrono; using namespace std::chrono;
} }
} }
future_vt test_mutex_push()
future_t<> test_mutex_push()
{ {
using namespace std::chrono; using namespace std::chrono;

+ 2
- 2
tutorial/test_async_routine.cpp View File

using namespace resumef; using namespace resumef;
future_vt test_routine_use_timer()
future_t<> test_routine_use_timer()
{ {
using namespace std::chrono; using namespace std::chrono;
std::cout << "test_routine_use_timer" << std::endl; std::cout << "test_routine_use_timer" << std::endl;
} }
} }
future_vt test_routine_use_timer_2()
future_t<> test_routine_use_timer_2()
{ {
std::cout << "test_routine_use_timer_2" << std::endl; std::cout << "test_routine_use_timer_2" << std::endl;

+ 3
- 3
tutorial/test_async_sleep.cpp View File

using namespace resumef; using namespace resumef;
future_vt test_sleep_use_timer()
future_t<> test_sleep_use_timer()
{ {
using namespace std::chrono; using namespace std::chrono;
event_t evts[8]; event_t evts[8];
go[&]() -> future_vt
go[&]() -> future_t<>
{ {
if (co_await event_t::wait_all(evts)) if (co_await event_t::wait_all(evts))
std::cout << "all event signal!" << std::endl; std::cout << "all event signal!" << std::endl;
srand((int)time(nullptr)); srand((int)time(nullptr));
for (size_t i = 0; i < _countof(evts); ++i) for (size_t i = 0; i < _countof(evts); ++i)
{ {
go[&, i]() -> future_vt
go[&, i]() -> future_t<>
{ {
co_await resumef::sleep_for(1ms * (500 + rand() % 1000)); co_await resumef::sleep_for(1ms * (500 + rand() % 1000));
evts[i].signal(); evts[i].signal();

+ 18
- 19
tutorial/test_async_suspend_always.cpp View File

using namespace resumef; using namespace resumef;
template<size_t _N>
future_vt test_loop_sleep()
future_t<> test_loop_sleep(size_t _N, char * ch)
{ {
using namespace std::chrono; using namespace std::chrono;
for (size_t i = 0; i < _N; ++i) for (size_t i = 0; i < _N; ++i)
{ {
co_await resumef::sleep_for(100ms); co_await resumef::sleep_for(100ms);
std::cout << ".";
std::cout << ch;
} }
std::cout << std::endl; std::cout << std::endl;
} }
future_vt test_recursive_await()
future_t<> test_recursive_await()
{ {
std::cout << "---1" << std::endl;
co_await test_loop_sleep<5>();
std::cout << "A:---1" << std::endl;
co_await test_loop_sleep(5, "=");
std::cout << "---2" << std::endl;
co_await test_loop_sleep<6>();
std::cout << "A:---2" << std::endl;
co_await test_loop_sleep(6, "=");
std::cout << "---3" << std::endl;
co_await test_loop_sleep<7>();
std::cout << "A:---3" << std::endl;
co_await test_loop_sleep(7, "=");
std::cout << "---4" << std::endl;
std::cout << "A:---4" << std::endl;
} }
future_vt test_recursive_go()
future_t<> test_recursive_go()
{ {
std::cout << "---1" << std::endl;
co_await test_loop_sleep<3>();
std::cout << "B:---1" << std::endl;
co_await test_loop_sleep(3, "+");
std::cout << "---2" << std::endl;
go test_loop_sleep<5>();
std::cout << "B:---2" << std::endl;
go test_loop_sleep(8, "*");
std::cout << "---3" << std::endl;
co_await test_loop_sleep<4>();
std::cout << "B:---3" << std::endl;
co_await test_loop_sleep(4, "+");
std::cout << "---4" << std::endl;
std::cout << "B:---4" << std::endl;
} }
void resumable_main_suspend_always() void resumable_main_suspend_always()

+ 3
- 3
tutorial/test_async_when_all.cpp View File

return dt; return dt;
}(), }(),
[]() ->future_vt
[]() ->future_t<>
{ {
auto dt = rand() % 1000; auto dt = rand() % 1000;
co_await sleep_for(1ms * dt); co_await sleep_for(1ms * dt);
std::cout << dt << "@b" << std::endl; std::cout << dt << "@b" << std::endl;
}(), }(),
[]() ->future_vt
[]() ->future_t<>
{ {
auto dt = rand() % 1000; auto dt = rand() % 1000;
co_await sleep_for(1ms * dt); co_await sleep_for(1ms * dt);
return dt; return dt;
}; };
auto my_sleep_v = [](const char * name) -> future_vt
auto my_sleep_v = [](const char * name) -> future_t<>
{ {
auto dt = rand() % 1000; auto dt = rand() % 1000;
co_await sleep_for(1ms * dt); co_await sleep_for(1ms * dt);

+ 2
- 2
vs_proj/librf.cpp View File

int main(int argc, const char* argv[]) int main(int argc, const char* argv[])
{ {
resumable_main_cb(); resumable_main_cb();
resumable_main_suspend_always();
//resumable_main_exception();
/* /*
resumable_main_resumable(); resumable_main_resumable();
resumable_main_multi_thread(); resumable_main_multi_thread();
resumable_main_yield_return(); resumable_main_yield_return();
resumable_main_timer(); resumable_main_timer();
resumable_main_suspend_always();
resumable_main_sleep(); resumable_main_sleep();
resumable_main_routine(); resumable_main_routine();
resumable_main_resumable(); resumable_main_resumable();
resumable_main_dynamic_go(); resumable_main_dynamic_go();
resumable_main_channel(); resumable_main_channel();
resumable_main_cb(); resumable_main_cb();
resumable_main_exception();
*/ */
return 0; return 0;

+ 5
- 12
vs_proj/librf.vcxproj View File

</ClCompile> </ClCompile>
<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\sleep.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\librf\src\sleep.cpp" />
<ClCompile Include="..\librf\src\state.cpp" /> <ClCompile Include="..\librf\src\state.cpp" />
<ClCompile Include="..\librf\src\timer.cpp" /> <ClCompile Include="..\librf\src\timer.cpp" />
<ClCompile Include="..\librf\src\when.cpp"> <ClCompile Include="..\librf\src\when.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
</ClCompile> </ClCompile>
<ClCompile Include="..\tutorial\test_async_exception.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\tutorial\test_async_exception.cpp" />
<ClCompile Include="..\tutorial\test_async_modern_cb.cpp"> <ClCompile Include="..\tutorial\test_async_modern_cb.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
</ClCompile> </ClCompile>
<ClCompile Include="..\tutorial\test_async_sleep.cpp"> <ClCompile Include="..\tutorial\test_async_sleep.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile> </ClCompile>
<ClCompile Include="..\tutorial\test_async_suspend_always.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\tutorial\test_async_suspend_always.cpp" />
<ClCompile Include="..\tutorial\test_async_timer.cpp"> <ClCompile Include="..\tutorial\test_async_timer.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>

+ 1
- 1
vs_proj/librf.vcxproj.filters View File

<Filter>librf\src</Filter> <Filter>librf\src</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\librf\src\awaitable.h"> <ClInclude Include="..\librf\src\awaitable.h">
<Filter>librf</Filter>
<Filter>librf\src</Filter>
</ClInclude> </ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

Loading…
Cancel
Save