7 #ifndef __MERCURY_COROUTINE_ENGINE_CONDITION_VARIABLE__
8 #define __MERCURY_COROUTINE_ENGINE_CONDITION_VARIABLE__
13 #include <condition_variable>
44 std::unique_lock<mce::spinlock> inner_lk(lk_);
47 auto key = borrow_key();
48 notify_queue_.push_back({ key, { &p, unparker{&p} }});
59 template <
class Lock,
class Pred>
60 void wait(Lock& lk, Pred p)
62 while(!p()) {
wait(lk); }
69 template <
class Lock,
class Rep,
class Period>
70 std::cv_status
wait_for(Lock& lk,
const std::chrono::duration<Rep, Period>& d)
80 template <
class Lock,
class Rep,
class Period,
class Pred>
81 bool wait_for(Lock& lk,
const std::chrono::duration<Rep, Period>& d, Pred p)
84 std::cv_status status = std::cv_status::no_timeout;
92 if(status == std::cv_status::timeout) {
break; }
102 template <
class Lock,
class Clock,
class Duration>
105 const std::chrono::time_point<Clock, Duration>& tp)
107 std::cv_status status = std::cv_status::no_timeout;
110 bool notify_available =
true;
113 std::unique_lock<mce::spinlock> lk(lk_);
117 auto key = borrow_key();
119 notify_queue_.push_back({
121 { &p, unparker_with_flag{&p, ¬ify_available} }
128 std::make_shared<clear_safe_handler::resumer>(
131 std::unique_lock<mce::spinlock> lk(lk_);
134 status = std::cv_status::timeout;
135 notify_with_key(lk,key);
164 template <
class Lock,
class Clock,
class Duration,
class Pred>
166 std::chrono::time_point<Clock, Duration> tp,
175 std::unique_lock<mce::spinlock> lk(lk_);
176 auto it = notify_queue_.begin();
177 if(it != notify_queue_.end())
179 it->second((
void*)&lk);
180 notify_queue_.erase(it);
187 std::unique_lock<mce::spinlock> lk(lk_);
188 auto it = notify_queue_.begin();
189 while(it != notify_queue_.end())
191 it->second((
void*)&lk);
194 notify_queue_.clear();
198 typedef size_t key_type;
199 typedef std::deque<std::pair<key_type,scheduler::parkable_notify>> notify_queue;
202 struct clear_safe_handler
215 inline void operator()(){ }
217 std::shared_ptr<resumer> resumer_;
223 inline void operator()(
void* m) { p_->unpark(*((std::unique_lock<mce::spinlock>*)m)); }
224 scheduler::parkable* p_;
227 struct unparker_with_flag
229 unparker_with_flag(scheduler::parkable* p,
bool* flag) :
234 inline void operator()(
void* m)
242 p_->unpark(*((std::unique_lock<mce::spinlock>*)m));
246 scheduler::parkable* p_;
252 inline size_t borrow_key()
256 if(!free_keys_.empty())
258 ret = free_keys_.front();
259 free_keys_.pop_front();
270 inline void return_key(key_type key) { free_keys_.push_back(key); }
274 inline void notify_with_key(std::unique_lock<mce::spinlock>& lk, key_type key)
276 notify_queue::iterator it;
277 for(it = notify_queue_.begin(); it != notify_queue_.end(); ++it)
281 it->second((
void*)&lk);
282 notify_queue_.erase(it);
289 notify_queue notify_queue_;
290 std::deque<key_type> free_keys_;
291 size_t key_source_ = 0;
result
enum for channel operation results
Definition: base_channel.hpp:23
std::function< void()> thunk
thunk type definition. Also known as a nullary function
Definition: function_utility.hpp:72
Definition: condition_variable.hpp:205
Definition: condition_variable.hpp:28
std::cv_status wait_until(Lock &user_lk, const std::chrono::time_point< Clock, Duration > &tp)
Definition: condition_variable.hpp:103
void wait_until(Lock &lk, std::chrono::time_point< Clock, Duration > tp, Pred p)
Definition: condition_variable.hpp:165
void notify_all()
Unblock all contexts calling a wait operation.
Definition: condition_variable.hpp:185
bool wait_for(Lock &lk, const std::chrono::duration< Rep, Period > &d, Pred p)
Definition: condition_variable.hpp:81
std::cv_status wait_for(Lock &lk, const std::chrono::duration< Rep, Period > &d)
Definition: condition_variable.hpp:70
void wait(Lock &lk, Pred p)
Definition: condition_variable.hpp:60
void notify_one()
Unblock one context calling a wait operation.
Definition: condition_variable.hpp:173
void wait(Lock &lk)
Definition: condition_variable.hpp:39
object containing information to block and unblock a coroutine (running in a scheduler) or thread
Definition: scheduler.hpp:268
void park(LOCK &lk)
blocking call until unpark, unlocks and relocks given lock as necessary
Definition: scheduler.hpp:283
Core mechanism for atomic synchronization.
Definition: atomic.hpp:20
Definition: timer.hpp:133
Definition: timer.hpp:131
timer_id timer(const mce::time_point &timeout, THUNK &&timeout_handler)
start timer
Definition: timer.hpp:205
bool remove(timer_id id)
remove a running timer
Definition: timer.hpp:281
mce::time_point current_time()
Return the current time. All mce timer time operations are calculated using this function.
Definition: timer.hpp:103
timer_service & default_timer_service()
Access to default mce::timer_service object.