// 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_SHARED_STATE_H namespace ircd::ctx { enum class future_state :uintptr_t; struct shared_state_base; struct promise_base; template struct shared_state; template<> struct shared_state; IRCD_EXCEPTION(ircd::ctx::error, future_error) future_state state(const shared_state_base &); bool is(const shared_state_base &, const future_state &); void set(shared_state_base &, const future_state &); size_t refcount(const shared_state_base &); void invalidate(shared_state_base &); void update(shared_state_base &); void notify(shared_state_base &); } /// Internal state enumeration for the promise / future / related. These can /// all be observed through state() or is(); only some can be set(). This is /// not for public manipulation. enum class ircd::ctx::future_state :uintptr_t { INVALID = 0, ///< Null. PENDING = 1, ///< Promise is attached and busy. READY = 2, ///< Result ready; promise is gone. OBSERVED = 3, ///< Special case for when_*(); not a state; promise is gone. RETRIEVED = 4, ///< User retrieved future value; promise is gone. }; /// Internal Non-template base of the state object shared by promise and /// future. It is extended by the appropriate template, and usually resides /// in the future's instance, where the promise finds it. struct ircd::ctx::shared_state_base { mutable dock cond; std::exception_ptr eptr; std::function then; union { promise_base *p {nullptr}; future_state st; }; shared_state_base(promise_base &p); shared_state_base() = default; shared_state_base(shared_state_base &&) = default; shared_state_base(const shared_state_base &) = delete; shared_state_base &operator=(shared_state_base &&) = default; shared_state_base &operator=(const shared_state_base &) = delete; ~shared_state_base() noexcept; }; /// Internal shared state between future and promise appropos a future value. template struct ircd::ctx::shared_state :shared_state_base { using value_type = T; using pointer_type = T *; using reference_type = T &; T val; using shared_state_base::shared_state_base; using shared_state_base::operator=; }; /// Internal shared state between future and promise when there is no future /// value, only a notification of completion or exception. template<> struct ircd::ctx::shared_state :shared_state_base { using value_type = void; using shared_state_base::shared_state_base; using shared_state_base::operator=; };