BitShares-Core  4.0.0
BitShares blockchain implementation and command-line interface 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 
83  void _on_complete( detail::completion_handler* c );
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 
bool error() const
Definition: future.hpp:246
bool valid() const
Definition: future.hpp:311
void on_complete(CompletionHandler &&c)
Definition: future.hpp:274
static ptr create(const char *desc FC_TASK_NAME_DEFAULT_ARG)
Definition: future.hpp:114
a placeholder for the result of an asynchronous operation.
Definition: future.hpp:211
virtual ~promise()
Definition: future.hpp:112
#define FC_CANCELATION_REASON_DEFAULT_ARG
Definition: future.hpp:21
T wait(boost::signals2::signal< void(T)> &sig, const microseconds &timeout_us=microseconds::maximum())
Definition: signals.hpp:38
void on_complete(CompletionHandler &&c)
Definition: future.hpp:185
bool ready() const
Definition: future.hpp:243
const char * _cancellation_reason
Definition: future.hpp:101
static ptr create(const T &val)
Definition: future.hpp:118
bool canceled() const
Definition: future.hpp:312
std::shared_ptr< promise_base > ptr
Definition: future.hpp:63
void wait_until(const time_point &tp)
Definition: future.hpp:177
virtual ~promise()
Definition: future.hpp:163
future(typename promise< void >::ptr &&p)
Definition: future.hpp:286
virtual void on_complete(const void *v, const fc::exception_ptr &e)
Definition: future.hpp:42
const T & wait_until(const time_point &tp)
Definition: future.hpp:131
promise(T &&val)
Definition: future.hpp:153
promise(bool fulfilled, const char *desc)
Definition: future.hpp:190
promise(const char *desc)
Definition: future.hpp:189
bool error() const
Definition: future.hpp:330
void wait(const microseconds &timeout=microseconds::maximum())
Definition: future.hpp:299
promise(const T &val)
Definition: future.hpp:152
const T & wait_until(const time_point &tp) const
Definition: future.hpp:235
future(typename promise< T >::ptr &&p)
Definition: future.hpp:214
provides stack-based nullable value similar to boost::optional
Definition: optional.hpp:20
bool valid() const
Definition: future.hpp:240
optional< T > result
Definition: future.hpp:155
std::shared_ptr< exception > exception_ptr
Definition: exception.hpp:131
void cancel(const char *reason FC_CANCELATION_REASON_DEFAULT_ARG) const
Definition: future.hpp:332
future & operator=(future< void > &&f)
Definition: future.hpp:290
void cancel_and_wait(const char *reason FC_CANCELATION_REASON_DEFAULT_ARG)
Definition: future.hpp:251
const T & wait(const microseconds &timeout=microseconds::maximum())
Definition: future.hpp:127
completion_handler_impl(const Functor &f)
Definition: future.hpp:40
static ptr create(bool fulfilled, const char *desc FC_TASK_NAME_DEFAULT_ARG)
Definition: future.hpp:169
future & operator=(future< T > &&f)
Definition: future.hpp:218
void cancel_and_wait(const char *reason FC_CANCELATION_REASON_DEFAULT_ARG)
Definition: future.hpp:314
void set_value(const void_t &)
Definition: future.hpp:182
static ptr create(T &&val)
Definition: future.hpp:122
void set_value(const T &v)
Definition: future.hpp:136
void set_value(T &&v)
Definition: future.hpp:141
bool ready() const
Definition: future.hpp:327
void on_complete(CompletionHandler &&c)
Definition: future.hpp:147
#define FC_TASK_NAME_DEFAULT_ARG
Definition: future.hpp:14
future(const future< T > &f)
Definition: future.hpp:215
Defines exception&#39;s used by fc.
future(const typename promise< T >::ptr &p)
Definition: future.hpp:213
void cancel(const char *reason FC_CANCELATION_REASON_DEFAULT_ARG) const
Definition: future.hpp:248
void wait(const microseconds &timeout=microseconds::maximum())
Definition: future.hpp:174
const T & wait(const microseconds &timeout=microseconds::maximum()) const
Definition: future.hpp:228
void wait_until(const time_point &tp)
Definition: future.hpp:307
Definition: api.hpp:15
promise(const char *desc)
Definition: future.hpp:151
virtual void on_complete(const void *v, const fc::exception_ptr &e)
Definition: future.hpp:53
future(const typename promise< void >::ptr &p)
Definition: future.hpp:285
std::shared_ptr< promise< void > > ptr
Definition: future.hpp:161
bool canceled() const
Definition: future.hpp:249
static microseconds maximum()
Definition: time.hpp:15
future(const future< void > &f)
Definition: future.hpp:287
static ptr create(const char *desc FC_TASK_NAME_DEFAULT_ARG)
Definition: future.hpp:165
void on_complete(CompletionHandler &&c)
Definition: future.hpp:335
std::shared_ptr< promise< T > > ptr
Definition: future.hpp:111
bool canceled() const
Definition: future.hpp:69