11#pragma once
2- #include < fc/utility.hpp>
32#include < fc/time.hpp>
4- #include < fc/shared_ptr.hpp>
53#include < fc/exception/exception.hpp>
64#include < fc/thread/spin_yield_lock.hpp>
75#include < fc/optional.hpp>
6+ #include < memory>
87
9- #include < atomic>
8+ #include < boost/ atomic.hpp >
109
1110// #define FC_TASK_NAMES_ARE_MANDATORY 1
1211#ifdef FC_TASK_NAMES_ARE_MANDATORY
2322#endif
2423
2524namespace fc {
26- class abstract_thread ;
2725 struct void_t {};
2826 class priority ;
2927 class thread ;
@@ -34,13 +32,13 @@ namespace fc {
3432 virtual ~completion_handler (){};
3533 virtual void on_complete ( const void * v, const fc::exception_ptr& e ) = 0;
3634 };
37-
35+
3836 template <typename Functor, typename T>
3937 class completion_handler_impl : public completion_handler {
4038 public:
41- completion_handler_impl ( Functor&& f ):_func(fc ::move(f)){}
39+ completion_handler_impl ( Functor&& f ):_func(std ::move(f)){}
4240 completion_handler_impl ( const Functor& f ):_func(f){}
43-
41+
4442 virtual void on_complete ( const void * v, const fc::exception_ptr& e ) {
4543 _func ( *static_cast <const T*>(v), e);
4644 }
@@ -50,7 +48,7 @@ namespace fc {
5048 template <typename Functor>
5149 class completion_handler_impl <Functor,void > : public completion_handler {
5250 public:
53- completion_handler_impl ( Functor&& f ):_func(fc ::move(f)){}
51+ completion_handler_impl ( Functor&& f ):_func(std ::move(f)){}
5452 completion_handler_impl ( const Functor& f ):_func(f){}
5553 virtual void on_complete ( const void * v, const fc::exception_ptr& e ) {
5654 _func (e);
@@ -60,10 +58,10 @@ namespace fc {
6058 };
6159 }
6260
63- class promise_base : public virtual retainable {
61+ class promise_base : public std ::enable_shared_from_this<promise_base> {
6462 public:
65- typedef fc ::shared_ptr<promise_base> ptr;
66- promise_base (const char * desc FC_TASK_NAME_DEFAULT_ARG );
63+ typedef std ::shared_ptr<promise_base> ptr;
64+ virtual ~ promise_base ();
6765
6866 const char * get_desc ()const ;
6967
@@ -75,6 +73,8 @@ namespace fc {
7573 void set_exception ( const fc::exception_ptr& e );
7674
7775 protected:
76+ promise_base (const char * desc FC_TASK_NAME_DEFAULT_ARG);
77+
7878 void _wait ( const microseconds& timeout_us );
7979 void _wait_until ( const time_point& timeout_us );
8080 void _enqueue_thread ();
@@ -84,36 +84,46 @@ namespace fc {
8484 void _set_value (const void * v);
8585
8686 void _on_complete ( detail::completion_handler* c );
87- ~promise_base ();
8887
8988 private:
9089 friend class thread ;
9190 friend struct context ;
9291 friend class thread_d ;
9392
94- std::atomic_bool _ready;
93+ bool _ready;
9594 mutable spin_yield_lock _spin_yield;
9695 thread* _blocked_thread;
9796 unsigned _blocked_fiber_count;
9897 time_point _timeout;
9998 fc::exception_ptr _exceptp;
100- std::atomic_bool _canceled;
99+ bool _canceled;
101100#ifndef NDEBUG
102101 protected:
103102 const char * _cancellation_reason;
104103 private:
105104#endif
106- const char * _desc;
107- detail::completion_handler* _compl;
105+ const char * _desc;
106+ detail::completion_handler* _compl;
108107 };
109108
110- template <typename T = void >
109+ template <typename T = void >
111110 class promise : virtual public promise_base {
112111 public:
113- typedef fc::shared_ptr< promise<T> > ptr;
114- promise ( const char * desc FC_TASK_NAME_DEFAULT_ARG):promise_base(desc){}
115- promise ( const T& val ){ set_value (val); }
116- promise ( T&& val ){ set_value (fc::move (val) ); }
112+ typedef std::shared_ptr< promise<T> > ptr;
113+ virtual ~promise (){}
114+
115+ static ptr create ( const char * desc FC_TASK_NAME_DEFAULT_ARG )
116+ {
117+ return ptr ( new promise<T>( desc ) );
118+ }
119+ static ptr create ( const T& val )
120+ {
121+ return ptr ( new promise<T>( val ) );
122+ }
123+ static ptr create ( T&& val )
124+ {
125+ return ptr ( new promise<T>( std::move (val) ) );
126+ }
117127
118128 const T& wait (const microseconds& timeout = microseconds::maximum() ){
119129 this ->_wait ( timeout );
@@ -130,7 +140,7 @@ namespace fc {
130140 }
131141
132142 void set_value ( T&& v ) {
133- result = fc ::move (v);
143+ result = std ::move (v);
134144 _set_value (&*result);
135145 }
136146
@@ -139,16 +149,28 @@ namespace fc {
139149 _on_complete ( new detail::completion_handler_impl<CompletionHandler,T>(fc::forward<CompletionHandler>(c)) );
140150 }
141151 protected:
152+ promise ( const char * desc ):promise_base(desc){}
153+ promise ( const T& val ){ set_value (val); }
154+ promise ( T&& val ){ set_value (std::move (val) ); }
155+
142156 optional<T> result;
143- ~promise (){}
144157 };
145158
146159 template <>
147160 class promise <void > : virtual public promise_base {
148161 public:
149- typedef fc::shared_ptr< promise<void > > ptr;
150- promise ( const char * desc FC_TASK_NAME_DEFAULT_ARG):promise_base(desc){}
151- // promise( const void_t& ){ set_value(); }
162+ typedef std::shared_ptr< promise<void > > ptr;
163+
164+ virtual ~promise (){}
165+
166+ static ptr create ( const char * desc FC_TASK_NAME_DEFAULT_ARG )
167+ {
168+ return ptr ( new promise<void >( desc ) );
169+ }
170+ static ptr create ( bool fulfilled, const char * desc FC_TASK_NAME_DEFAULT_ARG )
171+ {
172+ return ptr ( new promise<void >( fulfilled, desc ) );
173+ }
152174
153175 void wait (const microseconds& timeout = microseconds::maximum() ){
154176 this ->_wait ( timeout );
@@ -165,34 +187,37 @@ namespace fc {
165187 _on_complete ( new detail::completion_handler_impl<CompletionHandler,void >(fc::forward<CompletionHandler>(c)) );
166188 }
167189 protected:
168- ~promise (){}
190+ promise ( const char * desc ):promise_base(desc){}
191+ promise ( bool fulfilled, const char * desc ){
192+ if ( fulfilled ) set_value ();
193+ }
169194 };
170-
195+
171196 /* *
172197 * @brief a placeholder for the result of an asynchronous operation.
173198 *
174- * By calling future<T>::wait() you will block the current fiber until
175- * the asynchronous operation completes.
199+ * By calling future<T>::wait() you will block the current fiber until
200+ * the asynchronous operation completes.
176201 *
177202 * If you would like to use an asynchronous interface instead of the synchronous
178203 * 'wait' method you could specify a CompletionHandler which is a method that takes
179204 * two parameters, a const reference to the value and an exception_ptr. If the
180205 * exception_ptr is set, the value reference is invalid and accessing it is
181- * 'undefined'.
206+ * 'undefined'.
182207 *
183208 * Promises have pointer semantics, futures have reference semantics that
184209 * contain a shared pointer to a promise.
185210 */
186- template <typename T>
211+ template <typename T>
187212 class future {
188213 public:
189- future ( const fc::shared_ptr< promise<T>> & p ):m_prom(p){}
190- future ( fc::shared_ptr< promise<T>> && p ):m_prom(fc ::move(p)){}
214+ future ( const typename promise<T>::ptr & p ):m_prom(p){}
215+ future ( typename promise<T>::ptr && p ):m_prom(std ::move(p)){}
191216 future (const future<T>& f ) : m_prom(f.m_prom){}
192217 future (){}
193218
194219 future& operator =(future<T>&& f ) {
195- fc_swap (m_prom,f.m_prom );
220+ std::swap (m_prom,f.m_prom );
196221 return *this ;
197222 }
198223
@@ -240,9 +265,6 @@ namespace fc {
240265 }
241266 }
242267
243- void set_value ( const T& v ) { m_prom->set_value (v); }
244- void set_value ( T&& v ) { m_prom->set_value (v); }
245-
246268 /* *
247269 * @pre valid()
248270 *
@@ -256,19 +278,19 @@ namespace fc {
256278 }
257279 private:
258280 friend class thread ;
259- fc::shared_ptr< promise<T>> m_prom;
281+ typename promise<T>::ptr m_prom;
260282 };
261283
262284 template <>
263285 class future <void > {
264286 public:
265- future ( const fc::shared_ptr< promise<void >> & p ):m_prom(p){}
266- future ( fc::shared_ptr< promise<void >> && p ):m_prom(fc ::move(p)){}
287+ future ( const typename promise<void >::ptr & p ):m_prom(p){}
288+ future ( typename promise<void >::ptr && p ):m_prom(std ::move(p)){}
267289 future (const future<void >& f ) : m_prom(f.m_prom){}
268290 future (){}
269291
270292 future& operator =(future<void >&& f ) {
271- fc_swap (m_prom,f.m_prom );
293+ std::swap (m_prom,f.m_prom );
272294 return *this ;
273295 }
274296
@@ -291,7 +313,7 @@ namespace fc {
291313 bool valid ()const { return !!m_prom; }
292314 bool canceled ()const { return m_prom ? m_prom->canceled () : true ; }
293315
294- void cancel_and_wait (const char * reason FC_CANCELATION_REASON_DEFAULT_ARG)
316+ void cancel_and_wait (const char * reason FC_CANCELATION_REASON_DEFAULT_ARG)
295317 {
296318 cancel (reason);
297319 try
@@ -311,17 +333,13 @@ namespace fc {
311333
312334 void cancel (const char * reason FC_CANCELATION_REASON_DEFAULT_ARG) const { if ( m_prom ) m_prom->cancel (reason); }
313335
314- void set_value (){ m_prom->set_value (); }
315- void set_value ( const void_t & ) { m_prom->set_value (); }
316-
317336 template <typename CompletionHandler>
318337 void on_complete ( CompletionHandler&& c ) {
319338 m_prom->on_complete ( fc::forward<CompletionHandler>(c) );
320339 }
321340
322341 private:
323342 friend class thread ;
324- fc::shared_ptr< promise<void >> m_prom;
343+ typename promise<void >::ptr m_prom;
325344 };
326345}
327-
0 commit comments