libqi-api  release-2.5.3-2016-11-18
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
futurebarrier.hpp
Go to the documentation of this file.
1 #pragma once
2 /*
3 ** Copyright (C) 2015 Aldebaran Robotics
4 ** See COPYING for the license
5 */
6 
7 #ifndef QI_DETAIL_FUTURE_BARRIER_HXX_
8 #define QI_DETAIL_FUTURE_BARRIER_HXX_
9 
10 namespace qi
11 {
12 
13 namespace detail
14 {
15 
16 template<typename T>
18 public:
21  : _closed(0)
22  , _count(0)
23  , _futures()
24  , _promise(&qi::PromiseNoop<std::vector<Future<T> > >, async)
25  {}
26 
27  void onFutureFinish() {
28  if (--(this->_count) == 0 && this->_closed.load()) {
29  if (!_set.swap(true))
30  this->_promise.setValue(this->_futures);
31  }
32  }
33 
34  void cancelAll() {
36  for (typename std::vector< Future<T> >::iterator it = this->_futures.begin();
37  it != this->_futures.end();
38  ++it)
39  it->cancel();
40  }
41 
45  std::vector< Future<T> > _futures;
47 
48 };
49 
50 }
51 
163 template<typename T>
164 class FutureBarrier : boost::noncopyable {
165 public:
168  : _p(boost::make_shared<detail::FutureBarrierPrivate<T> >(async))
169  {
170  _p->_promise.setOnCancel(qi::bindWithFallback(
171  boost::function<void()>(),
173  boost::weak_ptr<detail::FutureBarrierPrivate<T> >(_p)));
174  }
175 
189  // Can't add future from closed qi::FutureBarrier.
190  if (_p->_closed.load())
191  throw std::runtime_error("Adding future to closed barrier");
192 
193  ++(_p->_count);
195  _p->_futures.push_back(fut);
196  }
197 
210  this->close();
211  return _p->_promise.future();
212  }
213 
214 protected:
215  boost::shared_ptr<detail::FutureBarrierPrivate<T> > _p;
216 
217 private:
218  void close() {
219  _p->_closed = true;
220  if (_p->_count.load() == 0) {
221  if (!_p->_set.swap(true))
222  _p->_promise.setValue(_p->_futures);
223  }
224  }
225 };
226 
236 template <typename T>
238  typename std::vector< Future<T> >::iterator it;
239  qi::FutureBarrier<T> barrier;
240 
241  for (it = vect.begin(); it != vect.end(); ++it) {
242  barrier.addFuture(*it);
243  }
244  return barrier.future();
245 }
246 
258 template <typename T>
260  typename std::vector< Future<T> >::iterator it;
262  qi::Atomic<int>* count = new qi::Atomic<int>();
263  count->swap((int)vect.size());
264  for (it = vect.begin(); it != vect.end(); ++it) {
265  it->connect(boost::bind<void>(&detail::waitForFirstHelper<T>, prom, *it, count));
266  }
267  return prom.future();
268 }
269 
270 }
271 
272 #endif
FutureBarrier(FutureCallbackType async=FutureCallbackType_Async)
FutureBarrier constructor taking no argument.
T swap(T value)
Definition: atomic.hpp:197
void connect(const AF &fun, FutureCallbackType type=FutureCallbackType_Auto)
Definition: future_fwd.hpp:484
void PromiseNoop(qi::Promise< T > &)
Helper function that does nothing on future cancelation.
Definition: future_fwd.hpp:953
void addFuture(qi::Future< T > fut)
Adds the future to the barrier.
This class helps waiting on multiple futures at the same point.
std::enable_if< std::is_function< RF >::value, boost::function< RF > >::type bindWithFallback(boost::function< void()> onFail, AF &&fun, Arg0 &&arg0, Args &&...args)
Definition: trackable.hxx:310
#define QI_ASSERT(expr__)
Definition: assert.hpp:27
Future< std::vector< Future< T > > > future()
Gets the future result for the barrier.
qi::FutureSync< std::vector< Future< T > > > waitForAll(std::vector< Future< T > > &vect)
Helper function to wait on a vector of futures.
std::vector< Future< T > > _futures
Future< T > future() const
Get a future linked to this promise. Can be called multiple times.
Definition: future_fwd.hpp:786
Future< R > async(boost::function< R()> callback, uint64_t usDelay)
Definition: eventloop.hpp:186
Promise< std::vector< Future< T > > > _promise
FutureCallbackType
Definition: future_fwd.hpp:83
FutureBarrierPrivate(FutureCallbackType async=FutureCallbackType_Async)
FutureBarrier constructor taking no argument.
boost::shared_ptr< detail::FutureBarrierPrivate< T > > _p
qi::FutureSync< qi::Future< T > > waitForFirst(std::vector< Future< T > > &vect)
Helper function to wait for the first valid future.
T load() const
Definition: atomic.hpp:208