1 //  Copyright (c) 2007-2012 Hartmut Kaiser
2 //
3 //  Distributed under the Boost Software License, Version 1.0. (See accompanying
4 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 
6 #if !defined(HPX_LCOS_LOCAL_CONDITIONAL_TRIGGER_SEP_09_2012_1256PM)
7 #define HPX_LCOS_LOCAL_CONDITIONAL_TRIGGER_SEP_09_2012_1256PM
8 
9 #include <hpx/config.hpp>
10 #include <hpx/error_code.hpp>
11 #include <hpx/exception_fwd.hpp>
12 #include <hpx/lcos/future.hpp>
13 #include <hpx/lcos/local/promise.hpp>
14 #include <hpx/util/assert.hpp>
15 #include <hpx/util/function.hpp>
16 
17 #include <utility>
18 
19 namespace hpx { namespace lcos { namespace local
20 {
21     ///////////////////////////////////////////////////////////////////////////
22     struct conditional_trigger
23     {
24     public:
conditional_triggerhpx::lcos::local::conditional_trigger25         conditional_trigger()
26         {
27         }
28 
conditional_triggerhpx::lcos::local::conditional_trigger29         conditional_trigger(conditional_trigger && rhs)
30           : cond_(std::move(rhs.cond_))
31         {
32         }
33 
operator =hpx::lcos::local::conditional_trigger34         conditional_trigger& operator=(conditional_trigger && rhs)
35         {
36             if (this != &rhs)
37             {
38                 promise_ = std::move(rhs.promise_);
39                 cond_ = std::move(rhs.cond_);
40             }
41             return *this;
42         }
43 
44         /// \brief get a future allowing to wait for the trigger to fire
45         template <typename Condition>
get_futurehpx::lcos::local::conditional_trigger46         future<void> get_future(Condition&& func,
47             error_code& ec = hpx::throws)
48         {
49             cond_.assign(std::forward<Condition>(func));
50 
51             future<void> f = promise_.get_future(ec);
52 
53             set(ec);      // trigger as soon as possible
54 
55             return f;
56         }
57 
resethpx::lcos::local::conditional_trigger58         void reset()
59         {
60             cond_.reset();
61         }
62 
63         /// \brief Trigger this object.
sethpx::lcos::local::conditional_trigger64         bool set(error_code& ec = throws)
65         {
66             if (&ec != &throws)
67                 ec = make_success_code();
68 
69             // trigger this object
70             if (cond_ && cond_())
71             {
72                 promise_.set_value();           // fire event
73                 promise_ = promise<void>();
74                 return true;
75             }
76 
77             return false;
78         }
79 
80     private:
81         lcos::local::promise<void> promise_;
82         util::function_nonser<bool()> cond_;
83     };
84 }}}
85 
86 #endif
87