it's not needed/desirable to hold onto the lock while notifying

master
Daniel Kolesa 2017-03-20 02:44:38 +01:00
parent 23652409f6
commit e50a86f339
2 changed files with 14 additions and 17 deletions

View File

@ -70,15 +70,17 @@ private:
impl() {} impl() {}
template<typename F> template<typename F>
impl(F &func): p_lock(), p_cond(func(p_lock)) {} impl(F &func): p_lock(), p_cond(func()) {}
template<typename U> template<typename U>
void put(U &&val) { void put(U &&val) {
std::lock_guard<std::mutex> l{p_lock}; {
if (p_closed) { std::lock_guard<std::mutex> l{p_lock};
throw channel_error{"put in a closed channel"}; if (p_closed) {
throw channel_error{"put in a closed channel"};
}
p_messages.push_back(std::forward<U>(val));
} }
p_messages.push_back(std::forward<U>(val));
p_cond.notify_one(); p_cond.notify_one();
} }
@ -106,8 +108,10 @@ private:
} }
void close() { void close() {
std::lock_guard<std::mutex> l{p_lock}; {
p_closed = true; std::lock_guard<std::mutex> l{p_lock};
p_closed = true;
}
p_cond.notify_all(); p_cond.notify_all();
} }

View File

@ -88,9 +88,7 @@ private:
coro_cond &operator=(coro_cond const &) = delete; coro_cond &operator=(coro_cond const &) = delete;
coro_cond &operator=(coro_cond &&) = delete; coro_cond &operator=(coro_cond &&) = delete;
coro_cond(basic_simple_coroutine_scheduler &s, std::mutex &mtx): coro_cond(basic_simple_coroutine_scheduler &s): p_sched(s) {}
p_sched(s), p_mtx(mtx)
{}
template<typename L> template<typename L>
void wait(L &l) noexcept { void wait(L &l) noexcept {
@ -104,20 +102,15 @@ private:
void notify_one() noexcept { void notify_one() noexcept {
p_notified = true; p_notified = true;
p_mtx.unlock();
p_sched.yield(); p_sched.yield();
p_mtx.lock();
} }
void notify_all() noexcept { void notify_all() noexcept {
p_notified = true; p_notified = true;
p_mtx.unlock();
p_sched.yield(); p_sched.yield();
p_mtx.lock();
} }
private: private:
basic_simple_coroutine_scheduler &p_sched; basic_simple_coroutine_scheduler &p_sched;
std::mutex &p_mtx;
bool p_notified = false; bool p_notified = false;
}; };
@ -182,8 +175,8 @@ public:
template<typename T> template<typename T>
channel<T, coro_cond> make_channel() { channel<T, coro_cond> make_channel() {
return channel<T, coro_cond>{[this](std::mutex &mtx) { return channel<T, coro_cond>{[this]() {
return coro_cond{*this, mtx}; return coro_cond{*this};
}}; }};
} }
private: private: