From f61d0a30ec1c2f300a883e9ef88bdd0264aeafbd Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Fri, 1 Jun 2018 10:37:51 -0700 Subject: [PATCH] ircd::ctx: Add condition_variable for interface compat. --- include/ircd/ctx/condition_variable.h | 150 ++++++++++++++++++++++++++ include/ircd/ctx/ctx.h | 1 + 2 files changed, 151 insertions(+) create mode 100644 include/ircd/ctx/condition_variable.h diff --git a/include/ircd/ctx/condition_variable.h b/include/ircd/ctx/condition_variable.h new file mode 100644 index 000000000..e86fab8b4 --- /dev/null +++ b/include/ircd/ctx/condition_variable.h @@ -0,0 +1,150 @@ +// Matrix Construct +// +// Copyright (C) Matrix Construct Developers, Authors & Contributors +// Copyright (C) 2016-2018 Jason Volk +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice is present in all copies. The +// full license for this software is available in the LICENSE file. + +#pragma once +#define HAVE_IRCD_CTX_CONDITION_VARIABLE_H + +namespace ircd::ctx +{ + struct condition_variable; +} + +struct ircd::ctx::condition_variable +{ + dock d; + + public: + template bool wait_until(lock &, time_point&& tp, predicate&& pred); + template std::cv_status wait_until(lock &, time_point&& tp); + + template bool wait_for(lock &, const duration &dur, predicate&& pred); + template std::cv_status wait_for(lock &, const duration &dur); + + template void wait(lock &, predicate&& pred); + template void wait(lock &); + + void notify_all() noexcept; + void notify_one() noexcept; + void notify() noexcept; +}; + +inline void +ircd::ctx::condition_variable::notify() +noexcept +{ + d.notify(); +} + +inline void +ircd::ctx::condition_variable::notify_one() +noexcept +{ + d.notify_one(); +} + +inline void +ircd::ctx::condition_variable::notify_all() +noexcept +{ + d.notify_all(); +} + +template +void +ircd::ctx::condition_variable::wait(lock &l) +{ + const unlock_guard ul(l); + d.wait(); +} + +template +void +ircd::ctx::condition_variable::wait(lock &l, + predicate&& pred) +{ + const unlock_guard ul(l); + return d.wait([&l, &pred] + { + l.lock(); + const unwind ul{[&l] + { + l.unlock(); + }}; + + return pred(); + }); +} + +template +std::cv_status +ircd::ctx::condition_variable::wait_for(lock &l, + const duration &dur) +{ + const unlock_guard ul(l); + return d.wait_for(dur)? + std::cv_status::no_timeout: + std::cv_status::timeout; +} + +template +bool +ircd::ctx::condition_variable::wait_for(lock &l, + const duration &dur, + predicate&& pred) +{ + const unlock_guard ul(l); + return d.wait_for(dur, [&l, &pred] + { + l.lock(); + const unwind ul{[&l] + { + l.unlock(); + }}; + + return pred(); + }); +} + +template +std::cv_status +ircd::ctx::condition_variable::wait_until(lock &l, + time_point&& tp) +{ + const unlock_guard ul(l); + return d.wait_until(std::forward(tp))? + std::cv_status::no_timeout: + std::cv_status::timeout; +} + +template +bool +ircd::ctx::condition_variable::wait_until(lock &l, + time_point&& tp, + predicate&& pred) +{ + const unlock_guard ul(l); + return d.wait_until(std::forward(tp), [&l, &pred] + { + l.lock(); + const unwind ul{[&l] + { + l.unlock(); + }}; + + return pred(); + }); +} diff --git a/include/ircd/ctx/ctx.h b/include/ircd/ctx/ctx.h index 105b6fcfb..c4f1061d2 100644 --- a/include/ircd/ctx/ctx.h +++ b/include/ircd/ctx/ctx.h @@ -81,6 +81,7 @@ namespace ircd::ctx #include "mutex.h" #include "shared_mutex.h" #include "unlock_guard.h" +#include "condition_variable.h" #include "peek.h" #include "view.h" #include "shared_state.h"