/home/users/khuck/src/hpx-lsu/hpx/lcos/promise.hpp

Line% of fetchesSource
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.