/* * 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_JS_CONTRACT_H namespace ircd { namespace js { // contract is a promise from C to a future in JS. When a task has no more pending contracts, // it ceases to exist. // // * The promise is the `struct contract` instantiated in C. // * The future is returned into JS as an object trapped by "future" (future.so) // * C unconditionally enters the closure to report result. // * * if the C closure returns a `value` the "value" field is set in JS // * * if the C closure throws an exception the "error" field conveys the exception in JS // * // * "id": uint // * "value": object [optional] // * "error": exception object [optional] // struct contract :std::weak_ptr { using closure = std::function; object future; operator const object &() const { return future; } operator object &() { return future; } operator value() const { return future; } // Enter this closure and return or throw to complete the result contract. void operator()(const closure &) noexcept; // The future object is constructed using the "future" trap. // The task is automatically found with task::get() in the overload without a task argument. contract(struct task &, object::handle future); contract(object::handle future); contract(contract &&) = default; contract(const contract &) = default; ~contract() noexcept; }; } // namespace js } // namespace ircd