| Line | % of fetches | Source |
|---|---|---|
| 1 | // Copyright (c) 2007-2015 Hartmut Kaiser | |
| 2 | // Copyright (c) 2016 Thomas Heller | |
| 3 | // Copyright (c) 2011 Bryce Adelstein-Lelbach | |
| 4 | // | |
| 5 | // Distributed under the Boost Software License, Version 1.0. (See accompanying | |
| 6 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
| 7 | ||
| 8 | #ifndef HPX_LCOS_PROMISE_HPP | |
| 9 | #define HPX_LCOS_PROMISE_HPP | |
| 10 | ||
| 11 | #include <hpx/config.hpp> | |
| 12 | #include <hpx/lcos/detail/promise_base.hpp> | |
| 13 | ||
| 14 | #include <boost/exception_ptr.hpp> | |
| 15 | ||
| 16 | #include <utility> | |
| 17 | ||
| 18 | namespace hpx { | |
| 19 | namespace lcos { | |
| 20 | /////////////////////////////////////////////////////////////////////////// | |
| 21 | /// A promise can be used by a single \a thread to invoke a | |
| 22 | /// (remote) action and wait for the result. The result is expected to be | |
| 23 | /// sent back to the promise using the LCO's set_event action | |
| 24 | /// | |
| 25 | /// A promise is one of the simplest synchronization primitives | |
| 26 | /// provided by HPX. It allows to synchronize on a eager evaluated remote | |
| 27 | /// operation returning a result of the type \a Result. The \a promise | |
| 28 | /// allows to synchronize exactly one \a thread (the one passed during | |
| 29 | /// construction time). | |
| 30 | /// | |
| 31 | /// \code | |
| 32 | /// // Create the promise (the expected result is a id_type) | |
| 33 | /// lcos::promise<naming::id_type> p; | |
| 34 | /// | |
| 35 | /// // Get the associated future | |
| 36 | /// future<naming::id_type> f = p.get_future(); | |
| 37 | /// | |
| 38 | /// // initiate the action supplying the promise as a | |
| 39 | /// // continuation | |
| 40 | /// apply<some_action>(new continuation(p.get_id()), ...); | |
| 41 | /// | |
| 42 | /// // Wait for the result to be returned, yielding control | |
| 43 | /// // in the meantime. | |
| 44 | /// naming::id_type result = f.get(); | |
| 45 | /// // ... | |
| 46 | /// \endcode | |
| 47 | /// | |
| 48 | /// \tparam Result The template parameter \a Result defines the type this | |
| 49 | /// promise is expected to return from | |
| 50 | /// \a promise#get. | |
| 51 | /// \tparam RemoteResult The template parameter \a RemoteResult defines the | |
| 52 | /// type this promise is expected to receive | |
| 53 | /// from the remote action. | |
| 54 | /// | |
| 55 | /// \note The action executed by the promise must return a value | |
| 56 | /// of a type convertible to the type as specified by the | |
| 57 | /// template parameter \a RemoteResult | |
| 58 | /////////////////////////////////////////////////////////////////////////// | |
| 59 | template <typename Result, typename RemoteResult> | |
| 60 | class promise | |
| 61 | : public detail::promise_base< | |
| 62 | Result, RemoteResult, detail::promise_data<Result> > | |
| 63 | { | |
| 64 | HPX_MOVABLE_ONLY(promise); | |
| 65 | ||
| 66 | typedef detail::promise_base< | |
| 67 | Result, RemoteResult, detail::promise_data<Result> | |
| 68 | > base_type; | |
| 69 | ||
| 70 | public: | |
| 71 | // Effects: constructs a promise object and a shared state. | |
| 72 | promise() | |
| 73 | : base_type() | |
| 74 | {} | |
| 75 | ||
| 76 | // Effects: constructs a new promise object and transfers ownership of | |
| 77 | // the shared state of other (if any) to the newly- | |
| 78 | // constructed object. | |
| 79 | // Postcondition: other has no shared state. | |
| 80 | promise(promise&& other) HPX_NOEXCEPT : base_type(std::move(other)) | |
| 81 | {} | |
| 82 | ||
| 83 | // Effects: Abandons any shared state | |
| 84 | ~promise() | |
| 85 | { | |
| 86 | } | |
| 87 | ||
| 88 | // Effects: Abandons any shared state (30.6.4) and then as if | |
| 89 | // promise(std::move(other)).swap(*this). | |
| 90 | // Returns: *this. | |
| 91 | promise& operator=(promise&& other) HPX_NOEXCEPT | |
| 92 | { | |
| 93 | base_type::operator=(std::move(other)); | |
| 94 | return *this; | |
| 95 | } | |
| 96 | ||
| 97 | // Effects: Exchanges the shared state of *this and other. | |
| 98 | // Postcondition: *this has the shared state (if any) that other had | |
| 99 | // prior to the call to swap. other has the shared state | |
| 100 | // (if any) that *this had prior to the call to swap. | |
| 101 | void swap(promise& other) HPX_NOEXCEPT | |
| 102 | { | |
| 103 | base_type::swap(other); | |
| 104 | } | |
| 105 | ||
| 106 | // Returns: true only if *this refers to a shared state. | |
| 107 | using base_type::valid; | |
| 108 | ||
| 109 | // Returns: A future<Result> object with the same shared state as *this. | |
| 110 | // Throws: future_error if *this has no shared state or if get_future | |
| 111 | // has already been called on a promise with the same shared | |
| 112 | // state as *this. | |
| 113 | // Error conditions: | |
| 114 | // - future_already_retrieved if get_future has already been called | |
| 115 | // on a promise with the same shared state as *this. | |
| 116 | // - no_state if *this has no shared state. | |
| 117 | using base_type::get_future; | |
| 118 | ||
| 119 | // Effects: atomically stores the value r in the shared state and makes | |
| 120 | // that state ready (30.6.4). | |
| 121 | // Throws: | |
| 122 | // - future_error if its shared state already has a stored value or | |
| 123 | // exception. | |
| 124 | // Error conditions: | |
| 125 | // - promise_already_satisfied if its shared state already has a | |
| 126 | // stored value or exception. | |
| 127 | // - no_state if *this has no shared state. | |
| 128 | using base_type::set_value; | |
| 129 | ||
| 130 | // Effects: atomically stores the exception pointer p in the shared | |
| 131 | // state and makes that state ready (30.6.4). | |
| 132 | // Throws: future_error if its shared state already has a stored value | |
| 133 | // or exception. | |
| 134 | // Error conditions: | |
| 135 | // - promise_already_satisfied if its shared state already has a | |
| 136 | // stored value or exception. | |
| 137 | // - no_state if *this has no shared state. | |
| 138 | using base_type::set_exception; | |
| 139 | }; | |
| 140 | ||
| 141 | template <> | |
| 142 | class promise<void, hpx::util::unused_type> | |
| 143 | : public detail::promise_base< | |
| 144 | void, hpx::util::unused_type, detail::promise_data<void> > | |
| 145 | { | |
| 146 | HPX_MOVABLE_ONLY(promise); | |
| 147 | ||
| 148 | typedef detail::promise_base< | |
| 149 | void, hpx::util::unused_type, detail::promise_data<void> | |
| 150 | > base_type; | |
| 151 | ||
| 152 | public: | |
| 153 | // Effects: constructs a promise object and a shared state. | |
| 154 | promise() | |
| 155 | : base_type() | |
| 156 | {} | |
| 157 | ||
| 158 | // Effects: constructs a new promise object and transfers ownership of | |
| 159 | // the shared state of other (if any) to the newly- | |
| 160 | // constructed object. | |
| 161 | // Postcondition: other has no shared state. | |
| 162 | promise(promise&& other) HPX_NOEXCEPT : base_type(std::move(other)) | |
| 163 | {} | |
| 164 | ||
| 165 | // Effects: Abandons any shared state | |
| 166 | ~promise() | |
| 167 | {} | |
| 168 | ||
| 169 | // Effects: Abandons any shared state (30.6.4) and then as if | |
| 170 | // promise(std::move(other)).swap(*this). | |
| 171 | // Returns: *this. | |
| 172 | promise& operator=(promise&& other) HPX_NOEXCEPT | |
| 173 | { | |
| 174 | base_type::operator=(std::move(other)); | |
| 175 | return *this; | |
| 176 | } | |
| 177 | ||
| 178 | // Effects: Exchanges the shared state of *this and other. | |
| 179 | // Postcondition: *this has the shared state (if any) that other had | |
| 180 | // prior to the call to swap. other has the shared state | |
| 181 | // (if any) that *this had prior to the call to swap. | |
| 182 | void swap(promise& other) HPX_NOEXCEPT | |
| 183 | { | |
| 184 | base_type::swap(other); | |
| 185 | } | |
| 186 | ||
| 187 | // Returns: true only if *this refers to a shared state. | |
| 188 | using base_type::valid; | |
| 189 | ||
| 190 | // Returns: A future<Result> object with the same shared state as *this. | |
| 191 | // Throws: future_error if *this has no shared state or if get_future | |
| 192 | // has already been called on a promise with the same shared | |
| 193 | // state as *this. | |
| 194 | // Error conditions: | |
| 195 | // - future_already_retrieved if get_future has already been called | |
| 196 | // on a promise with the same shared state as *this. | |
| 197 | // - no_state if *this has no shared state. | |
| 198 | using base_type::get_future; | |
| 199 | ||
| 200 | // Effects: atomically stores the value r in the shared state and makes | |
| 201 | // that state ready (30.6.4). | |
| 202 | // Throws: | |
| 203 | // - future_error if its shared state already has a stored value or | |
| 204 | // exception, or | |
| 205 | // - any exception thrown by the constructor selected to copy an | |
| 206 | // object of R. | |
| 207 | // Error conditions: | |
| 208 | // - promise_already_satisfied if its shared state already has a | |
| 209 | // stored value or exception. | |
| 210 | // - no_state if *this has no shared state. | |
| 211 | void set_value(error_code& ec = throws) | |
| 212 | { | |
| 213 | base_type::set_value(hpx::util::unused, ec); | |
| 214 | } | |
| 215 | ||
| 216 | // Effects: atomically stores the exception pointer p in the shared | |
| 217 | // state and makes that state ready (30.6.4). | |
| 218 | // Throws: future_error if its shared state already has a stored value | |
| 219 | // or exception. | |
| 220 | // Error conditions: | |
| 221 | // - promise_already_satisfied if its shared state already has a | |
| 222 | // stored value or exception. | |
| 223 | // - no_state if *this has no shared state. | |
| 224 | using base_type::set_exception; | |
| 225 | }; | |
| 226 | ||
| 227 | template <typename Result, typename RemoteResult> | |
| 228 | void swap(promise<Result, RemoteResult>& x, | |
| 229 | promise<Result, RemoteResult>& y) HPX_NOEXCEPT | |
| 230 | { | |
| 231 | x.swap(y); | |
| 232 | } | |
| 233 | }} | |
| 234 | ||
| 235 | #endif /*HPX_LCOS_PROMISE_HPP*/ | |
| 236 |
Copyright (c) 2006-2012 Rogue Wave Software, Inc. All Rights Reserved.
Patents pending.