From 5e8c4bb2a1f76c3ddf60df5142628fedc0052596 Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Mon, 19 Sep 2016 20:07:30 -0700 Subject: [PATCH] ircd::ctx: Add async() function. --- include/ircd/ctx_async.h | 95 +++++++++++++++++++++++++++++++++++++++ include/ircd/ctx_future.h | 14 +++--- include/ircd/stdinc.h | 1 + 3 files changed, 103 insertions(+), 7 deletions(-) create mode 100644 include/ircd/ctx_async.h diff --git a/include/ircd/ctx_async.h b/include/ircd/ctx_async.h new file mode 100644 index 000000000..09b1e3d42 --- /dev/null +++ b/include/ircd/ctx_async.h @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2016 Charybdis Development Team + * Copyright (C) 2016 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once +#define HAVE_IRCD_CTX_ASYNC_H + +namespace ircd { +namespace ctx { + +template +constexpr bool +is_void_result() +{ + return std::is_void::type>::value; +} + +template +using future_void = typename std::enable_if(), future>::type; + +template +using future_value = typename std::enable_if(), + future::type>>::type; + +template +future_value +async(F&& f, + A&&... a) +{ + using R = typename std::result_of::type; + + auto func(std::bind(std::forward(f), std::forward(a)...)); + auto p(std::make_shared>()); + auto wrapper([p, func(std::move(func))] + () mutable -> void + { + p->set_value(func()); + }); + + future ret(*p); + //TODO: DEFER_POST? + context(stack_size, std::move(wrapper), SELF_DESTRUCT | DEFER_POST | flags); + return ret; +} + +template +future_void +async(F&& f, + A&&... a) +{ + using R = typename std::result_of::type; + + auto func(std::bind(std::forward(f), std::forward(a)...)); + auto p(std::make_shared>()); + auto wrapper([p, func(std::move(func))] + () mutable -> void + { + func(); + p->set_value(); + }); + + future ret(*p); + //TODO: DEFER_POST? + context(stack_size, std::move(wrapper), SELF_DESTRUCT | DEFER_POST | flags); + return ret; +} + +} // namespace ctx +} // namespace ircd diff --git a/include/ircd/ctx_future.h b/include/ircd/ctx_future.h index f8b897663..6a71cba4e 100644 --- a/include/ircd/ctx_future.h +++ b/include/ircd/ctx_future.h @@ -42,16 +42,16 @@ class future using pointer_type = typename shared_state::pointer_type; using reference_type = typename shared_state::reference_type; - bool valid() const { return bool(st); } - bool operator!() const { return !valid(); } - operator bool() const { return valid(); } + bool valid() const { return bool(st); } + bool operator!() const { return !valid(); } + operator bool() const { return valid(); } template future_status wait_until(const time_point &) const; template future_status wait(const duration &d) const; void wait() const; T get(); - operator T() { return get(); } + operator T() { return get(); } future(); future(promise &promise); @@ -65,9 +65,9 @@ class future public: using value_type = typename shared_state::value_type; - bool valid() const { return bool(st); } - bool operator!() const { return !valid(); } - operator bool() const { return valid(); } + bool valid() const { return bool(st); } + bool operator!() const { return !valid(); } + operator bool() const { return valid(); } template future_status wait_until(const time_point &) const; template future_status wait(const duration &d) const; diff --git a/include/ircd/stdinc.h b/include/ircd/stdinc.h index 210745100..d1165ec65 100644 --- a/include/ircd/stdinc.h +++ b/include/ircd/stdinc.h @@ -95,6 +95,7 @@ namespace ircd #include "ctx_shared_state.h" #include "ctx_promise.h" #include "ctx_future.h" +#include "ctx_async.h" #include "line.h" #include "tape.h"