BitShares-Core  7.0.2
BitShares blockchain node software and command-line wallet software
future.hpp
Go to the documentation of this file.
1 #pragma once
2 #include <fc/time.hpp>
5 #include <fc/optional.hpp>
6 
7 #include <atomic>
8 #include <memory>
9 
10 //#define FC_TASK_NAMES_ARE_MANDATORY 1
11 #ifdef FC_TASK_NAMES_ARE_MANDATORY
12 # define FC_TASK_NAME_DEFAULT_ARG
13 #else
14 # define FC_TASK_NAME_DEFAULT_ARG = "?"
15 #endif
16 
17 //#define FC_CANCELATION_REASONS_ARE_MANDATORY 1
18 #ifdef FC_CANCELATION_REASONS_ARE_MANDATORY
19 # define FC_CANCELATION_REASON_DEFAULT_ARG
20 #else
21 # define FC_CANCELATION_REASON_DEFAULT_ARG = nullptr
22 #endif
23 
24 namespace fc {
25  struct void_t{};
26  class priority;
27  class thread;
28 
29  namespace detail {
31  public:
32  virtual ~completion_handler(){};
33  virtual void on_complete( const void* v, const fc::exception_ptr& e ) = 0;
34  };
35 
36  template<typename Functor, typename T>
38  public:
39  completion_handler_impl( Functor&& f ):_func(std::move(f)){}
40  completion_handler_impl( const Functor& f ):_func(f){}
41 
42  virtual void on_complete( const void* v, const fc::exception_ptr& e ) {
43  _func( *static_cast<const T*>(v), e);
44  }
45  private:
46  Functor _func;
47  };
48  template<typename Functor>
49  class completion_handler_impl<Functor,void> : public completion_handler {
50  public:
51  completion_handler_impl( Functor&& f ):_func(std::move(f)){}
52  completion_handler_impl( const Functor& f ):_func(f){}
53  virtual void on_complete( const void* v, const fc::exception_ptr& e ) {
54  _func(e);
55  }
56  private:
57  Functor _func;
58  };
59  }
60 
61  class promise_base : public std::enable_shared_from_this<promise_base> {
62  public:
63  typedef std::shared_ptr<promise_base> ptr;
64  virtual ~promise_base();
65 
66  const char* get_desc()const;
67 
68  virtual void cancel(const char* reason FC_CANCELATION_REASON_DEFAULT_ARG);
69  bool canceled()const { return _canceled; }
70  bool ready()const;
71  bool error()const;
72 
73  void set_exception( const fc::exception_ptr& e );
74 
75  protected:
76  promise_base(const char* desc FC_TASK_NAME_DEFAULT_ARG);
77 
78  void _wait( const microseconds& timeout_us );
79  void _wait_until( const time_point& timeout_us );
80  void _notify();
81  void _set_value(const void* v);
82 
84 
85  private:
86  void _enqueue_thread();
87  void _dequeue_thread();
88 
89  friend class thread;
90  friend struct context;
91  friend class thread_d;
92 
93  std::atomic<bool> _ready;
94  std::atomic<thread*> _blocked_thread;
95  std::atomic<int32_t> _blocked_fiber_count;
96  time_point _timeout;
97  fc::exception_ptr _exceptp;
98  bool _canceled;
99 #ifndef NDEBUG
100  protected:
101  const char* _cancellation_reason;
102  private:
103 #endif
104  const char* _desc;
105  std::atomic<detail::completion_handler*> _compl;
106  };
107 
108  template<typename T = void>
109  class promise : virtual public promise_base {
110  public:
111  typedef std::shared_ptr< promise<T> > ptr;
112  virtual ~promise(){}
113 
114  static ptr create( const char* desc FC_TASK_NAME_DEFAULT_ARG )
115  {
116  return ptr( new promise<T>( desc ) );
117  }
118  static ptr create( const T& val )
119  {
120  return ptr( new promise<T>( val ) );
121  }
122  static ptr create( T&& val )
123  {
124  return ptr( new promise<T>( std::move(val) ) );
125  }
126 
127  const T& wait(const microseconds& timeout = microseconds::maximum() ){
128  this->_wait( timeout );
129  return *result;
130  }
131  const T& wait_until(const time_point& tp ) {
132  this->_wait_until( tp );
133  return *result;
134  }
135 
136  void set_value( const T& v ) {
137  result = v;
138  _set_value(&*result);
139  }
140 
141  void set_value( T&& v ) {
142  result = std::move(v);
143  _set_value(&*result);
144  }
145 
146  template<typename CompletionHandler>
147  void on_complete( CompletionHandler&& c ) {
148  _on_complete( new detail::completion_handler_impl<CompletionHandler,T>(std::forward<CompletionHandler>(c)) );
149  }
150  protected:
151  promise( const char* desc ):promise_base(desc){}
152  promise( const T& val ){ set_value(val); }
153  promise( T&& val ){ set_value(std::move(val) ); }
154 
156  };
157 
158  template<>
159  class promise<void> : virtual public promise_base {
160  public:
161  typedef std::shared_ptr< promise<void> > ptr;
162 
163  virtual ~promise(){}
164 
165  static ptr create( const char* desc FC_TASK_NAME_DEFAULT_ARG )
166  {
167  return ptr( new promise<void>( desc ) );
168  }
169  static ptr create( bool fulfilled, const char* desc FC_TASK_NAME_DEFAULT_ARG )
170  {
171  return ptr( new promise<void>( fulfilled, desc ) );
172  }
173 
174  void wait(const microseconds& timeout = microseconds::maximum() ){
175  this->_wait( timeout );
176  }
177  void wait_until(const time_point& tp ) {
178  this->_wait_until( tp );
179  }
180 
181  void set_value(){ this->_set_value(nullptr); }
182  void set_value( const void_t& ) { this->_set_value(nullptr); }
183 
184  template<typename CompletionHandler>
185  void on_complete( CompletionHandler&& c ) {
186  _on_complete( new detail::completion_handler_impl<CompletionHandler,void>(std::forward<CompletionHandler>(c)) );
187  }
188  protected:
189  promise( const char* desc ):promise_base(desc){}
190  promise( bool fulfilled, const char* desc ){
191  if( fulfilled ) set_value();
192  }
193  };
194 
210  template<typename T>
211  class future {
212  public:
213  future( const typename promise<T>::ptr& p ):m_prom(p){}
214  future( typename promise<T>::ptr&& p ):m_prom(std::move(p)){}
215  future(const future<T>& f ) : m_prom(f.m_prom){}
216  future(){}
217 
219  std::swap(m_prom,f.m_prom);
220  return *this;
221  }
222 
223  operator const T&()const { return wait(); }
224 
228  const T& wait( const microseconds& timeout = microseconds::maximum() )const {
229  return m_prom->wait(timeout);
230  }
231 
235  const T& wait_until( const time_point& tp )const {
236  if( m_prom )
237  return m_prom->wait_until(tp);
238  }
239 
240  bool valid()const { return !!m_prom; }
241 
243  bool ready()const { return m_prom->ready(); }
244 
246  bool error()const { return m_prom->error(); }
247 
248  void cancel(const char* reason FC_CANCELATION_REASON_DEFAULT_ARG) const { if( m_prom ) m_prom->cancel(reason); }
249  bool canceled()const { if( m_prom ) return m_prom->canceled(); else return true;}
250 
252  {
253  if( valid() )
254  {
255  cancel(reason);
256  try
257  {
258  wait();
259  }
260  catch (const canceled_exception&)
261  {
262  }
263  }
264  }
265 
273  template<typename CompletionHandler>
274  void on_complete( CompletionHandler&& c ) {
275  m_prom->on_complete( std::forward<CompletionHandler>(c) );
276  }
277  private:
278  friend class thread;
279  typename promise<T>::ptr m_prom;
280  };
281 
282  template<>
283  class future<void> {
284  public:
285  future( const typename promise<void>::ptr& p ):m_prom(p){}
286  future( typename promise<void>::ptr&& p ):m_prom(std::move(p)){}
287  future(const future<void>& f ) : m_prom(f.m_prom){}
288  future(){}
289 
291  std::swap(m_prom,f.m_prom);
292  return *this;
293  }
294 
295 
299  void wait( const microseconds& timeout = microseconds::maximum() ){
300  if( m_prom )
301  m_prom->wait(timeout);
302  }
303 
307  void wait_until( const time_point& tp ) {
308  m_prom->wait_until(tp);
309  }
310 
311  bool valid()const { return !!m_prom; }
312  bool canceled()const { return m_prom ? m_prom->canceled() : true; }
313 
315  {
316  cancel(reason);
317  try
318  {
319  wait();
320  }
321  catch (const canceled_exception&)
322  {
323  }
324  }
325 
327  bool ready()const { return m_prom->ready(); }
328 
330  bool error()const { return m_prom->error(); }
331 
332  void cancel(const char* reason FC_CANCELATION_REASON_DEFAULT_ARG) const { if( m_prom ) m_prom->cancel(reason); }
333 
334  template<typename CompletionHandler>
335  void on_complete( CompletionHandler&& c ) {
336  m_prom->on_complete( std::forward<CompletionHandler>(c) );
337  }
338 
339  private:
340  friend class thread;
341  typename promise<void>::ptr m_prom;
342  };
343 }
344 
fc::promise
Definition: future.hpp:109
fc::promise::on_complete
void on_complete(CompletionHandler &&c)
Definition: future.hpp:147
fc::promise_base::ready
bool ready() const
Definition: future.cpp:37
fc::promise_base::_cancellation_reason
const char * _cancellation_reason
Definition: future.hpp:101
fc::detail::completion_handler_impl::completion_handler_impl
completion_handler_impl(Functor &&f)
Definition: future.hpp:39
fc::promise_base::~promise_base
virtual ~promise_base()
Definition: future.cpp:24
fc::future::cancel
void cancel(const char *reason FC_CANCELATION_REASON_DEFAULT_ARG) const
Definition: future.hpp:248
fc::future
a placeholder for the result of an asynchronous operation.
Definition: future.hpp:211
fc::detail::completion_handler_impl< Functor, void >::completion_handler_impl
completion_handler_impl(const Functor &f)
Definition: future.hpp:52
fc::promise::ptr
std::shared_ptr< promise< T > > ptr
Definition: future.hpp:111
fc::promise::promise
promise(const T &val)
Definition: future.hpp:152
fc::future< void >::wait_until
void wait_until(const time_point &tp)
Definition: future.hpp:307
fc::promise::wait
const T & wait(const microseconds &timeout=microseconds::maximum())
Definition: future.hpp:127
fc::promise< void >::set_value
void set_value()
Definition: future.hpp:181
fc::detail::completion_handler_impl< Functor, void >::on_complete
virtual void on_complete(const void *v, const fc::exception_ptr &e)
Definition: future.hpp:53
fc::detail::completion_handler_impl< Functor, void >::completion_handler_impl
completion_handler_impl(Functor &&f)
Definition: future.hpp:51
fc::promise_base::canceled
bool canceled() const
Definition: future.hpp:69
fc::future< void >::future
future()
Definition: future.hpp:288
fc
Definition: api.hpp:15
fc::promise_base::promise_base
promise_base(const char *desc FC_TASK_NAME_DEFAULT_ARG)
Definition: future.cpp:11
fc::promise< void >::set_value
void set_value(const void_t &)
Definition: future.hpp:182
fc::thread_d
Definition: thread_d.hpp:30
fc::future< void >::error
bool error() const
Definition: future.hpp:330
fc::detail::completion_handler_impl::on_complete
virtual void on_complete(const void *v, const fc::exception_ptr &e)
Definition: future.hpp:42
fc::future::future
future(const typename promise< T >::ptr &p)
Definition: future.hpp:213
fc::detail::completion_handler_impl::completion_handler_impl
completion_handler_impl(const Functor &f)
Definition: future.hpp:40
fc::detail::completion_handler::~completion_handler
virtual ~completion_handler()
Definition: future.hpp:32
fc::future< void >::canceled
bool canceled() const
Definition: future.hpp:312
FC_CANCELATION_REASON_DEFAULT_ARG
#define FC_CANCELATION_REASON_DEFAULT_ARG
Definition: future.hpp:21
fc::promise_base::cancel
virtual void cancel(const char *reason FC_CANCELATION_REASON_DEFAULT_ARG)
Definition: future.cpp:30
fc::future::operator=
future & operator=(future< T > &&f)
Definition: future.hpp:218
fc::promise::create
static ptr create(const char *desc FC_TASK_NAME_DEFAULT_ARG)
Definition: future.hpp:114
fc::microseconds::maximum
static microseconds maximum()
Definition: time.hpp:15
fc::exception_ptr
std::shared_ptr< exception > exception_ptr
Definition: exception.hpp:131
fc::promise< void >::promise
promise(const char *desc)
Definition: future.hpp:189
fc::detail::completion_handler
Definition: future.hpp:30
fc::future::ready
bool ready() const
Definition: future.hpp:243
spin_yield_lock.hpp
fc::promise< void >::create
static ptr create(const char *desc FC_TASK_NAME_DEFAULT_ARG)
Definition: future.hpp:165
fc::promise< void >::on_complete
void on_complete(CompletionHandler &&c)
Definition: future.hpp:185
fc::context
Definition: context.hpp:47
fc::promise< void >::create
static ptr create(bool fulfilled, const char *desc FC_TASK_NAME_DEFAULT_ARG)
Definition: future.hpp:169
fc::future< void >::wait
void wait(const microseconds &timeout=microseconds::maximum())
Definition: future.hpp:299
fc::promise::set_value
void set_value(T &&v)
Definition: future.hpp:141
fc::promise::~promise
virtual ~promise()
Definition: future.hpp:112
fc::promise< void >::wait
void wait(const microseconds &timeout=microseconds::maximum())
Definition: future.hpp:174
fc::promise_base::error
bool error() const
Definition: future.cpp:40
fc::promise< void >::wait_until
void wait_until(const time_point &tp)
Definition: future.hpp:177
fc::promise::promise
promise(T &&val)
Definition: future.hpp:153
fc::future< void >::on_complete
void on_complete(CompletionHandler &&c)
Definition: future.hpp:335
fc::promise::create
static ptr create(const T &val)
Definition: future.hpp:118
fc::thread
Definition: thread.hpp:39
fc::future< void >::future
future(const future< void > &f)
Definition: future.hpp:287
fc::future< void >::operator=
future & operator=(future< void > &&f)
Definition: future.hpp:290
fc::future< void >::future
future(const typename promise< void >::ptr &p)
Definition: future.hpp:285
FC_TASK_NAME_DEFAULT_ARG
#define FC_TASK_NAME_DEFAULT_ARG
Definition: future.hpp:14
fc::promise_base::_notify
void _notify()
Definition: future.cpp:115
fc::promise< void >::promise
promise(bool fulfilled, const char *desc)
Definition: future.hpp:190
fc::future::canceled
bool canceled() const
Definition: future.hpp:249
fc::promise_base::_on_complete
void _on_complete(detail::completion_handler *c)
Definition: future.cpp:134
fc::promise_base::get_desc
const char * get_desc() const
Definition: future.cpp:26
fc::promise_base::_set_value
void _set_value(const void *v)
Definition: future.cpp:124
fc::detail::completion_handler_impl
Definition: future.hpp:37
fc::promise::wait_until
const T & wait_until(const time_point &tp)
Definition: future.hpp:131
fc::future< void >::valid
bool valid() const
Definition: future.hpp:311
fc::future< void >::cancel_and_wait
void cancel_and_wait(const char *reason FC_CANCELATION_REASON_DEFAULT_ARG)
Definition: future.hpp:314
fc::future::future
future()
Definition: future.hpp:216
fc::promise_base::_wait_until
void _wait_until(const time_point &timeout_us)
Definition: future.cpp:55
fc::future< void >::ready
bool ready() const
Definition: future.hpp:327
fc::microseconds
Definition: time.hpp:12
fc::promise::set_value
void set_value(const T &v)
Definition: future.hpp:136
fc::promise< void >::~promise
virtual ~promise()
Definition: future.hpp:163
fc::priority
Definition: priority.hpp:9
fc::void_t
Definition: future.hpp:25
fc::future::wait_until
const T & wait_until(const time_point &tp) const
Definition: future.hpp:235
fc::time_point
Definition: time.hpp:44
fc::promise_base
Definition: future.hpp:61
fc::future::wait
const T & wait(const microseconds &timeout=microseconds::maximum()) const
Definition: future.hpp:228
exception.hpp
Defines exception's used by fc.
std
Definition: zeroed_array.hpp:76
fc::promise< void >
Definition: future.hpp:159
fc::promise_base::ptr
std::shared_ptr< promise_base > ptr
Definition: future.hpp:63
fc::future::valid
bool valid() const
Definition: future.hpp:240
fc::promise_base::set_exception
void set_exception(const fc::exception_ptr &e)
Definition: future.cpp:44
fc::future< void >::future
future(typename promise< void >::ptr &&p)
Definition: future.hpp:286
fc::future< void >::cancel
void cancel(const char *reason FC_CANCELATION_REASON_DEFAULT_ARG) const
Definition: future.hpp:332
fc::promise::create
static ptr create(T &&val)
Definition: future.hpp:122
fc::future::future
future(const future< T > &f)
Definition: future.hpp:215
fc::optional
provides stack-based nullable value similar to boost::optional
Definition: optional.hpp:20
time.hpp
fc::promise< void >::ptr
std::shared_ptr< promise< void > > ptr
Definition: future.hpp:161
fc::detail::completion_handler::on_complete
virtual void on_complete(const void *v, const fc::exception_ptr &e)=0
fc::future::on_complete
void on_complete(CompletionHandler &&c)
Definition: future.hpp:274
fc::future::cancel_and_wait
void cancel_and_wait(const char *reason FC_CANCELATION_REASON_DEFAULT_ARG)
Definition: future.hpp:251
fc::future::error
bool error() const
Definition: future.hpp:246
fc::future::future
future(typename promise< T >::ptr &&p)
Definition: future.hpp:214
fc::promise::promise
promise(const char *desc)
Definition: future.hpp:151
fc::future< void >
Definition: future.hpp:283
fc::promise_base::_wait
void _wait(const microseconds &timeout_us)
Definition: future.cpp:49
fc::promise::result
optional< T > result
Definition: future.hpp:155
optional.hpp