Parcourir la source

支持when_all/when_any

tags/v2.9.7
tearshark il y a 6 ans
Parent
révision
803cc2e51e

+ 1
- 0
librf/librf.h Voir le fichier

@@ -21,3 +21,4 @@
#include "src/channel.h"
#include "src/scheduler.h"
#include "src/sleep.h"
#include "src/when.h"

+ 19
- 19
librf/src/channel.h Voir le fichier

@@ -166,47 +166,47 @@ namespace resumef
}
template<class _Ty2>
awaitable_t<bool> write(_Ty2&& val) const
future_t<bool> write(_Ty2&& val) const
{
awaitable_t<bool> awaitable;
promise_t<bool> awaitable;
auto awaker = std::make_shared<channel_write_awaker>(
[st = awaitable._state](channel_impl_type * chan) -> bool
{
st->set_value(chan ? true : false);
return true;
});
{
st->set_value(chan ? true : false);
return true;
});
_chan->write_(std::move(awaker), std::forward<_Ty2>(val));
return awaitable;
return awaitable.get_future();
}
awaitable_t<_Ty> read() const
future_t<_Ty> read() const
{
awaitable_t<_Ty> awaitable;
promise_t<_Ty> awaitable;
auto awaker = std::make_shared<channel_read_awaker>(
[st = awaitable._state](channel_impl_type *, _Ty * val, error_code fe) -> bool
{
if(val)
st->set_value(std::move(*val));
else
st->throw_exception(channel_exception{ fe });
{
if(val)
st->set_value(std::move(*val));
else
st->throw_exception(channel_exception{ fe });
return true;
});
return true;
});
_chan->read_(std::move(awaker));
return awaitable;
return awaitable.get_future();
}
template<class _Ty2>
awaitable_t<bool> operator << (_Ty2&& val) const
future_t<bool> operator << (_Ty2&& val) const
{
return std::move(write(std::forward<_Ty2>(val)));
}
awaitable_t<_Ty> operator co_await () const
future_t<_Ty> operator co_await () const
{
return read();
}

+ 21
- 21
librf/src/event.cpp Voir le fichier

@@ -66,9 +66,9 @@ namespace resumef
{
}
awaitable_t<bool> event_t::wait() const
future_t<bool> event_t::wait() const
{
awaitable_t<bool> awaitable;
promise_t<bool> awaitable;
auto awaker = std::make_shared<detail::event_awaker>(
[st = awaitable._state](detail::event_impl * e) -> bool
@@ -78,12 +78,12 @@ namespace resumef
});
_event->wait_(awaker);
return awaitable;
return awaitable.get_future();
}
awaitable_t<bool> event_t::wait_until_(const clock_type::time_point & tp) const
future_t<bool> event_t::wait_until_(const clock_type::time_point & tp) const
{
awaitable_t<bool> awaitable;
promise_t<bool> awaitable;
auto awaker = std::make_shared<detail::event_awaker>(
[st = awaitable._state](detail::event_impl * e) -> bool
@@ -99,7 +99,7 @@ namespace resumef
awaker->awake(nullptr, 1);
});
return awaitable;
return awaitable.get_future();
}
struct wait_any_awaker
@@ -137,14 +137,14 @@ namespace resumef
}
};
awaitable_t<intptr_t> event_t::wait_any_(std::vector<event_impl_ptr> && evts)
future_t<intptr_t> event_t::wait_any_(std::vector<event_impl_ptr> && evts)
{
awaitable_t<intptr_t> awaitable;
promise_t<intptr_t> awaitable;
if (evts.size() <= 0)
{
awaitable._state->set_value(-1);
return awaitable;
return awaitable.get_future();
}
auto awaker = std::make_shared<detail::event_awaker>(
@@ -174,12 +174,12 @@ namespace resumef
e->wait_(awaker);
}
return awaitable;
return awaitable.get_future();
}
awaitable_t<intptr_t> event_t::wait_any_until_(const clock_type::time_point & tp, std::vector<event_impl_ptr> && evts)
future_t<intptr_t> event_t::wait_any_until_(const clock_type::time_point & tp, std::vector<event_impl_ptr> && evts)
{
awaitable_t<intptr_t> awaitable;
promise_t<intptr_t> awaitable;
auto awaker = std::make_shared<detail::event_awaker>(
[st = awaitable._state, evts](detail::event_impl * e) -> bool
@@ -214,16 +214,16 @@ namespace resumef
awaker->awake(nullptr, 1);
});
return awaitable;
return awaitable.get_future();
}
awaitable_t<bool> event_t::wait_all_(std::vector<event_impl_ptr> && evts)
future_t<bool> event_t::wait_all_(std::vector<event_impl_ptr> && evts)
{
awaitable_t<bool> awaitable;
promise_t<bool> awaitable;
if (evts.size() <= 0)
{
awaitable._state->set_value(false);
return awaitable;
return awaitable.get_future();
}
auto awaker = std::make_shared<detail::event_awaker>(
@@ -239,7 +239,7 @@ namespace resumef
e->wait_(awaker);
}
return awaitable;
return awaitable.get_future();
}
@@ -319,9 +319,9 @@ namespace resumef
//超时后的行为应该表现为:
//要么所有的事件计数减一,要么所有事件计数不动
//则需要超时后,恢复已经等待的事件计数
awaitable_t<bool> event_t::wait_all_until_(const clock_type::time_point & tp, std::vector<event_impl_ptr> && evts)
future_t<bool> event_t::wait_all_until_(const clock_type::time_point & tp, std::vector<event_impl_ptr> && evts)
{
awaitable_t<bool> awaitable;
promise_t<bool> awaitable;
if (evts.size() <= 0)
{
this_scheduler()->timer()->add_handler(tp,
@@ -329,7 +329,7 @@ namespace resumef
{
st->set_value(false);
});
return awaitable;
return awaitable.get_future();
}
auto ctx = std::make_shared<wait_all_ctx>();
@@ -353,6 +353,6 @@ namespace resumef
}
return awaitable;
return awaitable.get_future();
}
}

+ 24
- 24
librf/src/event.h Voir le fichier

@@ -63,16 +63,16 @@ namespace resumef
RF_API awaitable_t<bool>
RF_API future_t<bool>
wait() const;
template<class _Rep, class _Period>
awaitable_t<bool>
future_t<bool>
wait_for(const std::chrono::duration<_Rep, _Period> & dt) const
{
return wait_for_(std::chrono::duration_cast<clock_type::duration>(dt));
}
template<class _Clock, class _Duration>
awaitable_t<bool>
future_t<bool>
wait_until(const std::chrono::time_point<_Clock, _Duration> & tp) const
{
return wait_until_(std::chrono::time_point_cast<clock_type::duration>(tp));
@@ -83,39 +83,39 @@ namespace resumef
template<class _Iter>
static awaitable_t<intptr_t>
static future_t<intptr_t>
wait_any(_Iter begin_, _Iter end_)
{
return wait_any_(make_event_vector(begin_, end_));
}
template<class _Cont>
static awaitable_t<intptr_t>
static future_t<intptr_t>
wait_any(const _Cont & cnt_)
{
return wait_any_(make_event_vector(std::begin(cnt_), std::end(cnt_)));
}
template<class _Rep, class _Period, class _Iter>
static awaitable_t<intptr_t>
static future_t<intptr_t>
wait_any_for(const std::chrono::duration<_Rep, _Period> & dt, _Iter begin_, _Iter end_)
{
return wait_any_for_(std::chrono::duration_cast<clock_type::duration>(dt), make_event_vector(begin_, end_));
}
template<class _Rep, class _Period, class _Cont>
static awaitable_t<intptr_t>
static future_t<intptr_t>
wait_any_for(const std::chrono::duration<_Rep, _Period> & dt, const _Cont & cnt_)
{
return wait_any_for_(std::chrono::duration_cast<clock_type::duration>(dt), make_event_vector(std::begin(cnt_), std::end(cnt_)));
}
template<class _Clock, class _Duration, class _Iter>
static awaitable_t<intptr_t>
static future_t<intptr_t>
wait_any_until(const std::chrono::time_point<_Clock, _Duration> & tp, _Iter begin_, _Iter end_)
{
return wait_any_until_(std::chrono::time_point_cast<clock_type::duration>(tp), make_event_vector(begin_, end_));
}
template<class _Clock, class _Duration, class _Cont>
static awaitable_t<intptr_t>
static future_t<intptr_t>
wait_any_until(const std::chrono::time_point<_Clock, _Duration> & tp, const _Cont & cnt_)
{
return wait_any_until_(std::chrono::time_point_cast<clock_type::duration>(tp), make_event_vector(std::begin(cnt_), std::end(cnt_)));
@@ -126,39 +126,39 @@ namespace resumef
template<class _Iter>
static awaitable_t<bool>
static future_t<bool>
wait_all(_Iter begin_, _Iter end_)
{
return wait_all_(make_event_vector(begin_, end_));
}
template<class _Cont>
static awaitable_t<bool>
static future_t<bool>
wait_all(const _Cont & cnt_)
{
return wait_all(std::begin(cnt_), std::end(cnt_));
}
template<class _Rep, class _Period, class _Iter>
static awaitable_t<bool>
static future_t<bool>
wait_all_for(const std::chrono::duration<_Rep, _Period> & dt, _Iter begin_, _Iter end_)
{
return wait_all_for_(std::chrono::duration_cast<clock_type::duration>(dt), make_event_vector(begin_, end_));
}
template<class _Rep, class _Period, class _Cont>
static awaitable_t<bool>
static future_t<bool>
wait_all_for(const std::chrono::duration<_Rep, _Period> & dt, const _Cont & cnt_)
{
return wait_all_for_(std::chrono::duration_cast<clock_type::duration>(dt), make_event_vector(std::begin(cnt_), std::end(cnt_)));
}
template<class _Clock, class _Duration, class _Iter>
static awaitable_t<bool>
static future_t<bool>
wait_all_until(const std::chrono::time_point<_Clock, _Duration> & tp, _Iter begin_, _Iter end_)
{
return wait_all_until_(std::chrono::time_point_cast<clock_type::duration>(tp), make_event_vector(begin_, end_));
}
template<class _Clock, class _Duration, class _Cont>
static awaitable_t<bool>
static future_t<bool>
wait_all_until(const std::chrono::time_point<_Clock, _Duration> & tp, const _Cont & cnt_)
{
return wait_all_until_(std::chrono::time_point_cast<clock_type::duration>(tp), make_event_vector(std::begin(cnt_), std::end(cnt_)));
@@ -166,7 +166,6 @@ namespace resumef
RF_API event_t(const event_t &) = default;
RF_API event_t(event_t &&) = default;
RF_API event_t & operator = (const event_t &) = default;
@@ -184,27 +183,28 @@ namespace resumef
return std::move(evts);
}
inline awaitable_t<bool> wait_for_(const clock_type::duration & dt) const
public:
inline future_t<bool> wait_for_(const clock_type::duration & dt) const
{
return wait_until_(clock_type::now() + dt);
}
RF_API awaitable_t<bool> wait_until_(const clock_type::time_point & tp) const;
RF_API future_t<bool> wait_until_(const clock_type::time_point & tp) const;
RF_API static awaitable_t<intptr_t> wait_any_(std::vector<event_impl_ptr> && evts);
inline static awaitable_t<intptr_t> wait_any_for_(const clock_type::duration & dt, std::vector<event_impl_ptr> && evts)
RF_API static future_t<intptr_t> wait_any_(std::vector<event_impl_ptr> && evts);
inline static future_t<intptr_t> wait_any_for_(const clock_type::duration & dt, std::vector<event_impl_ptr> && evts)
{
return wait_any_until_(clock_type::now() + dt, std::forward<std::vector<event_impl_ptr>>(evts));
}
RF_API static awaitable_t<intptr_t> wait_any_until_(const clock_type::time_point & tp, std::vector<event_impl_ptr> && evts);
RF_API static future_t<intptr_t> wait_any_until_(const clock_type::time_point & tp, std::vector<event_impl_ptr> && evts);
RF_API static awaitable_t<bool> wait_all_(std::vector<event_impl_ptr> && evts);
inline static awaitable_t<bool> wait_all_for_(const clock_type::duration & dt, std::vector<event_impl_ptr> && evts)
RF_API static future_t<bool> wait_all_(std::vector<event_impl_ptr> && evts);
inline static future_t<bool> wait_all_for_(const clock_type::duration & dt, std::vector<event_impl_ptr> && evts)
{
return wait_all_until_(clock_type::now() + dt, std::forward<std::vector<event_impl_ptr>>(evts));
}
RF_API static awaitable_t<bool> wait_all_until_(const clock_type::time_point & tp, std::vector<event_impl_ptr> && evts);
RF_API static future_t<bool> wait_all_until_(const clock_type::time_point & tp, std::vector<event_impl_ptr> && evts);
};
}

+ 6
- 4
librf/src/future.h Voir le fichier

@@ -20,8 +20,8 @@ namespace resumef
future_impl_t() = default;
future_impl_t(future_impl_t&& f) = default;
future_impl_t & operator = (future_impl_t&& f) = default;
future_impl_t(const future_impl_t&) = delete;
future_impl_t & operator = (const future_impl_t&) = delete;
future_impl_t(const future_impl_t&) = default;
future_impl_t & operator = (const future_impl_t&) = default;
//------------------------------------------------------------------------------------------
//以下是与编译器生成的resumable function交互的接口
@@ -78,11 +78,11 @@ namespace resumef
}
// movable, but not copyable
future_t(const future_t&) = delete;
future_t(const future_t&) = default;
future_t(future_t&& f) = default;
future_t() = default;
future_t & operator = (const future_t&) = delete;
future_t & operator = (const future_t&) = default;
future_t & operator = (future_t&& f) = default;
//------------------------------------------------------------------------------------------
@@ -290,6 +290,7 @@ namespace resumef
using promise_vt = promise_t<void>;
/*
template <typename T = void>
struct awaitable_t
{
@@ -331,6 +332,7 @@ namespace resumef
};
using awaitable_vt = awaitable_t<void>;
*/
#if RESUMEF_ENABLE_MULT_SCHEDULER
inline promise_t<void> * state_base::parent_promise() const

+ 6
- 6
librf/src/mutex.cpp Voir le fichier

@@ -78,9 +78,9 @@ namespace resumef
{
}
awaitable_t<bool> mutex_t::lock() const
future_t<bool> mutex_t::lock() const
{
awaitable_t<bool> awaitable;
promise_t<bool> awaitable;
auto awaker = std::make_shared<detail::mutex_awaker>(
[st = awaitable._state](detail::mutex_impl * e) -> bool
@@ -90,7 +90,7 @@ namespace resumef
});
_locker->lock_(awaker);
return awaitable;
return awaitable.get_future();
}
bool mutex_t::try_lock() const
@@ -103,9 +103,9 @@ namespace resumef
return _locker->try_lock_(dummy_awaker);
}
awaitable_t<bool> mutex_t::try_lock_until_(const clock_type::time_point & tp) const
future_t<bool> mutex_t::try_lock_until_(const clock_type::time_point & tp) const
{
awaitable_t<bool> awaitable;
promise_t<bool> awaitable;
auto awaker = std::make_shared<detail::mutex_awaker>(
[st = awaitable._state](detail::mutex_impl * e) -> bool
@@ -121,6 +121,6 @@ namespace resumef
awaker->awake(nullptr, 1);
});
return awaitable;
return awaitable.get_future();
}
}

+ 4
- 4
librf/src/mutex.h Voir le fichier

@@ -57,7 +57,7 @@ namespace resumef
}
RF_API awaitable_t<bool>
RF_API future_t<bool>
lock() const;
RF_API bool
try_lock() const;
@@ -83,13 +83,13 @@ namespace resumef
RF_API mutex_t & operator = (const mutex_t &) = default;
RF_API mutex_t & operator = (mutex_t &&) = default;
private:
inline awaitable_t<bool> try_lock_for_(const clock_type::duration & dt) const
inline future_t<bool> try_lock_for_(const clock_type::duration & dt) const
{
return try_lock_until_(clock_type::now() + dt);
}
RF_API awaitable_t<bool> try_lock_until_(const clock_type::time_point & tp) const;
RF_API future_t<bool> try_lock_until_(const clock_type::time_point & tp) const;
};
#define resumf_guard_lock(lker) (lker).lock(); resumef::scoped_lock<resumef::mutex_t> __resumf_guard##lker##__((lker), std::adopt_lock)
#define resumf_guard_lock(lker) (lker).lock(); resumef::scoped_lock<resumef::mutex_t> __resumf_guard##lker##__(std::adopt_lock, (lker))
}

+ 3
- 3
librf/src/sleep.cpp Voir le fichier

@@ -5,9 +5,9 @@
namespace resumef
{
awaitable_t<bool> sleep_until_(const std::chrono::system_clock::time_point& tp_, scheduler & scheduler_)
future_t<bool> sleep_until_(const std::chrono::system_clock::time_point& tp_, scheduler & scheduler_)
{
resumef::awaitable_t<bool> awaitable;
promise_t<bool> awaitable;
scheduler_.timer()->add(tp_,
[st = awaitable._state](bool cancellation_requested)
@@ -15,6 +15,6 @@ namespace resumef
st->set_value(cancellation_requested);
});
return awaitable;
return awaitable.get_future();
}
}

+ 6
- 6
librf/src/sleep.h Voir le fichier

@@ -4,31 +4,31 @@ namespace resumef
{
struct scheduler;
RF_API awaitable_t<bool> sleep_until_(const std::chrono::system_clock::time_point& tp_, scheduler & scheduler_);
RF_API future_t<bool> sleep_until_(const std::chrono::system_clock::time_point& tp_, scheduler & scheduler_);
inline awaitable_t<bool> sleep_for_(const std::chrono::system_clock::duration& dt_, scheduler & scheduler_)
inline future_t<bool> sleep_for_(const std::chrono::system_clock::duration& dt_, scheduler & scheduler_)
{
return std::move(sleep_until_(std::chrono::system_clock::now() + dt_, scheduler_));
}
template<class _Rep, class _Period>
awaitable_t<bool> sleep_for(const std::chrono::duration<_Rep, _Period>& dt_, scheduler & scheduler_)
future_t<bool> sleep_for(const std::chrono::duration<_Rep, _Period>& dt_, scheduler & scheduler_)
{
return std::move(sleep_for_(std::chrono::duration_cast<std::chrono::system_clock::duration>(dt_), scheduler_));
}
template<class _Rep, class _Period>
awaitable_t<bool> sleep_for(const std::chrono::duration<_Rep, _Period>& dt_)
future_t<bool> sleep_for(const std::chrono::duration<_Rep, _Period>& dt_)
{
return std::move(sleep_for_(std::chrono::duration_cast<std::chrono::system_clock::duration>(dt_), *this_scheduler()));
}
template<class _Clock, class _Duration = typename _Clock::duration>
awaitable_t<bool> sleep_until(const std::chrono::time_point<_Clock, _Duration>& tp_, scheduler & scheduler_)
future_t<bool> sleep_until(const std::chrono::time_point<_Clock, _Duration>& tp_, scheduler & scheduler_)
{
return std::move(sleep_until_(std::chrono::time_point_cast<std::chrono::system_clock::duration>(tp_), scheduler_));
}
template<class _Clock, class _Duration>
awaitable_t<bool> sleep_until(const std::chrono::time_point<_Clock, _Duration>& tp_)
future_t<bool> sleep_until(const std::chrono::time_point<_Clock, _Duration>& tp_)
{
return std::move(sleep_until_(std::chrono::time_point_cast<std::chrono::system_clock::duration>(tp_), *this_scheduler()));
}

+ 53
- 0
librf/src/when.cpp Voir le fichier

@@ -0,0 +1,53 @@
#include "when.h"
#include <assert.h>
#include "scheduler.h"
#pragma once
#include "_awaker.h"
namespace resumef
{
namespace detail
{
when_impl::when_impl(intptr_t initial_counter_)
: _counter(initial_counter_)
{
}
void when_impl::signal()
{
scoped_lock<lock_type> lock_(this->_lock);
if (--this->_counter == 0)
{
_awakes->awake(this, 1);
}
}
void when_impl::reset(intptr_t initial_counter_)
{
scoped_lock<lock_type> lock_(this->_lock);
this->_awakes = nullptr;
this->_counter = initial_counter_;
}
bool when_impl::wait_(const when_awaker_ptr & awaker)
{
assert(awaker);
scoped_lock<lock_type> lock_(this->_lock);
if (this->_counter == 0)
{
awaker->awake(this, 1);
return true;
}
else
{
this->_awakes = awaker;
return false;
}
}
}
}

+ 122
- 0
librf/src/when.h Voir le fichier

@@ -0,0 +1,122 @@
#pragma once
#include "_awaker.h"
namespace resumef
{
namespace detail
{
struct when_impl;
typedef _awaker<when_impl> when_awaker;
typedef std::shared_ptr<when_awaker> when_awaker_ptr;
struct when_impl : public std::enable_shared_from_this<when_impl>
{
private:
//typedef spinlock lock_type;
typedef std::recursive_mutex lock_type;
when_awaker_ptr _awakes;
intptr_t _counter;
lock_type _lock;
public:
RF_API when_impl(intptr_t initial_counter_);
RF_API void signal();
RF_API void reset(intptr_t initial_counter_);
//如果已经触发了awaker,则返回true
RF_API bool wait_(const when_awaker_ptr & awaker);
template<class callee_t, class dummy_t = std::enable_if<!std::is_same<std::remove_cv_t<callee_t>, event_awaker_ptr>::value>>
auto wait(callee_t && awaker, dummy_t * dummy_ = nullptr)
{
return wait_(std::make_shared<event_awaker>(std::forward<callee_t>(awaker)));
}
when_impl(const when_impl &) = delete;
when_impl(when_impl &&) = delete;
when_impl & operator = (const when_impl &) = delete;
when_impl & operator = (when_impl &&) = delete;
};
typedef std::shared_ptr<when_impl> when_impl_ptr;
template<class _Fty>
struct when_one_functor
{
when_impl_ptr _e;
mutable future_t<_Fty> _f;
when_one_functor(const detail::when_impl_ptr & e, future_t<_Fty> f)
:_e(e)
, _f(std::move(f))
{}
when_one_functor(when_one_functor &&) = default;
inline future_vt operator ()() const
{
co_await _f;
_e->signal();
}
};
inline void when_one__(scheduler * s, const detail::when_impl_ptr & e)
{
}
template<class _Fty, class... _Rest>
inline void when_one__(scheduler * s, const detail::when_impl_ptr & e, future_t<_Fty> f, _Rest&&... rest)
{
(*s) + when_one_functor<_Fty>{e, std::move(f)};
when_one__(s, e, std::forward<_Rest>(rest)...);
}
}
template<class... _Fty>
future_t<bool> when_count(size_t counter, scheduler * s, _Fty&&... f)
{
promise_t<bool> awaitable;
detail::when_impl_ptr _event = std::make_shared<detail::when_impl>(counter);
auto awaker = std::make_shared<detail::when_awaker>(
[st = awaitable._state](detail::when_impl * e) -> bool
{
st->set_value(e ? true : false);
return true;
});
_event->wait_(awaker);
detail::when_one__(s, _event, std::forward<_Fty>(f)...);
return awaitable.get_future();
}
template<class... _Fty>
future_t<bool> when_all(scheduler * s, _Fty&&... f)
{
return when_count(sizeof...(_Fty), s, std::forward<_Fty>(f)...);
}
template<class... _Fty>
future_t<bool> when_all(_Fty&&... f)
{
return when_count(sizeof...(_Fty), this_scheduler(), std::forward<_Fty>(f)...);
}
template<class... _Fty>
future_t<bool> when_any(scheduler * s, _Fty&&... f)
{
static_assert(sizeof...(_Fty) > 0);
return when_count(1, s, std::forward<_Fty>(f)...);
}
template<class... _Fty>
future_t<bool> when_any(_Fty&&... f)
{
static_assert(sizeof...(_Fty) > 0);
return when_count(1, this_scheduler(), std::forward<_Fty>(f)...);
}
}

+ 4
- 4
tutorial/test_async_exception.cpp Voir le fichier

@@ -12,7 +12,7 @@ using namespace resumef;
//请打开结构化异常(/EHa)
auto async_signal_exception(const intptr_t dividend)
{
awaitable_t<int64_t> awaitable;
promise_t<int64_t> awaitable;
std::thread([dividend, st = awaitable._state]
{
@@ -30,12 +30,12 @@ auto async_signal_exception(const intptr_t dividend)
}
}).detach();
return awaitable;
return awaitable.get_future();
}
auto async_signal_exception2(const intptr_t dividend)
{
awaitable_t<int64_t> awaitable;
promise_t<int64_t> awaitable;
std::thread([dividend, st = awaitable._state]
{
@@ -46,7 +46,7 @@ auto async_signal_exception2(const intptr_t dividend)
st->set_value(10000 / dividend);
}).detach();
return awaitable;
return awaitable.get_future();
}
future_vt test_signal_exception()

+ 2
- 2
tutorial/test_async_multi_thread.cpp Voir le fichier

@@ -15,7 +15,7 @@ auto async_heavy_computing_tasks(int64_t val)
{
using namespace std::chrono;
awaitable_t<int64_t> awaitable;
promise_t<int64_t> awaitable;
std::thread([val, st = awaitable._state]
{
@@ -23,7 +23,7 @@ auto async_heavy_computing_tasks(int64_t val)
st->set_value(val * val);
}).detach();
return awaitable;
return awaitable.get_future();
}
future_vt heavy_computing_sequential(int64_t val)

+ 74
- 0
tutorial/test_async_when_all.cpp Voir le fichier

@@ -0,0 +1,74 @@

#include <chrono>
#include <iostream>
#include <string>
#include <conio.h>
#include <thread>
#include <experimental/resumable>
#include "librf.h"
using namespace resumef;
void test_when_any()
{
using namespace std::chrono;
GO
{
co_await when_any(
[]() ->future_vt
{
auto dt = rand() % 1000;
co_await sleep_for(1ms * dt);
std::cout << dt << "@1000" << std::endl;
}(),
[]() ->future_vt
{
auto dt = rand() % 2000;
co_await sleep_for(1ms * dt);
std::cout << dt << "@2000" << std::endl;
}(),
[]() ->future_vt
{
auto dt = rand() % 3000;
co_await sleep_for(1ms * dt);
std::cout << dt << "@3000" << std::endl;
}());
std::cout << "any done!" << std::endl;
};
this_scheduler()->run_until_notask();
}
void test_when_all()
{
using namespace std::chrono;
auto my_sleep = [](const char * name) -> future_vt
{
auto dt = rand() % 1000;
co_await sleep_for(1ms * dt);
std::cout << dt << "@" << name << std::endl;
};
GO
{
co_await when_all();
std::cout << "zero!" << std::endl;
co_await when_all(my_sleep("a"), my_sleep("b"));
co_await my_sleep("c");
co_await when_all(my_sleep("d"), my_sleep("e"), my_sleep("f"));
std::cout << "all done!" << std::endl;
};
this_scheduler()->run_until_notask();
}
void resumable_main_when_all()
{
srand((uint32_t)time(nullptr));
test_when_any();
std::cout << std::endl;
test_when_all();
}

+ 2
- 1
vs_proj/librf.cpp Voir le fichier

@@ -16,12 +16,13 @@ extern void resumable_main_channel();
extern void resumable_main_cb();
extern void resumable_main_multi_thread();
extern void resumable_main_channel_mult_thread();
extern void resumable_main_when_all();
extern void resumable_main_benchmark_mem();
int main(int argc, const char * argv[])
{
resumable_main_channel_mult_thread();
resumable_main_when_all();
//resumable_main_multi_thread();
return 0;

+ 7
- 0
vs_proj/librf.vcxproj Voir le fichier

@@ -90,6 +90,7 @@
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\librf;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalOptions>/await /std:c++latest </AdditionalOptions>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@@ -104,6 +105,7 @@
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\librf;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalOptions>/await /std:c++latest </AdditionalOptions>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@@ -120,6 +122,7 @@
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\librf;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalOptions>/await /std:c++latest </AdditionalOptions>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@@ -146,6 +149,7 @@
<StringPooling>true</StringPooling>
<LanguageStandard>stdcpplatest</LanguageStandard>
<BufferSecurityCheck>false</BufferSecurityCheck>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@@ -165,6 +169,7 @@
<ClCompile Include="..\librf\src\sleep.cpp" />
<ClCompile Include="..\librf\src\state.cpp" />
<ClCompile Include="..\librf\src\timer.cpp" />
<ClCompile Include="..\librf\src\when.cpp" />
<ClCompile Include="..\tutorial\test_async_cb.cpp" />
<ClCompile Include="..\tutorial\test_async_channel.cpp" />
<ClCompile Include="..\tutorial\test_async_channel_mult_thread.cpp" />
@@ -179,6 +184,7 @@
<ClCompile Include="..\tutorial\test_async_sleep.cpp" />
<ClCompile Include="..\tutorial\test_async_suspend_always.cpp" />
<ClCompile Include="..\tutorial\test_async_timer.cpp" />
<ClCompile Include="..\tutorial\test_async_when_all.cpp" />
<ClCompile Include="..\tutorial\test_async_yield_return.cpp" />
<ClCompile Include="librf.cpp" />
</ItemGroup>
@@ -200,6 +206,7 @@
<ClInclude Include="..\librf\src\timer.h" />
<ClInclude Include="..\librf\src\unix\coroutine.h" />
<ClInclude Include="..\librf\src\utils.h" />
<ClInclude Include="..\librf\src\when.h" />
<ClInclude Include="..\librf\src\_awaker.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

+ 9
- 0
vs_proj/librf.vcxproj.filters Voir le fichier

@@ -94,6 +94,12 @@
<ClCompile Include="..\tutorial\test_async_channel_mult_thread.cpp">
<Filter>tutorial</Filter>
</ClCompile>
<ClCompile Include="..\tutorial\test_async_when_all.cpp">
<Filter>tutorial</Filter>
</ClCompile>
<ClCompile Include="..\librf\src\when.cpp">
<Filter>librf\src</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\librf\librf.h">
@@ -150,5 +156,8 @@
<ClInclude Include="..\librf\src\counted_ptr.h">
<Filter>librf\src</Filter>
</ClInclude>
<ClInclude Include="..\librf\src\when.h">
<Filter>librf\src</Filter>
</ClInclude>
</ItemGroup>
</Project>

Chargement…
Annuler
Enregistrer