libqi-api  release-2.5.3-2016-11-18
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
futuregroup.hpp
Go to the documentation of this file.
1 #pragma once
2 /*
3 ** Copyright (C) 2014 Aldebaran Robotics
4 ** See COPYING for the license
5 */
6 #include <boost/container/flat_map.hpp>
7 #include <boost/thread/mutex.hpp>
8 #include <qi/future.hpp>
9 #include <qi/trackable.hpp>
10 
11 namespace qi
12 {
21  : boost::noncopyable
22  , public qi::Trackable<ScopedFutureGroup>
23  {
24  public:
28  {
29  destroy();
30  cancelAll();
31  }
32 
39  template< class T >
40  void add(Future<T> future)
41  {
42  boost::mutex::scoped_lock lock(_mutex);
43  _futureCancelList.emplace(future.uniqueId(), [future]() mutable { future.cancel(); });
44 
45  // The 2 following lines are necessary because of a compiler bug in VS2010 which is fixed in VS2015 and beyond
46  future.then([&](Future<T> f){ onFutureFinished(f); });
47  }
48 
51  void cancelAll()
52  {
53  FutureCancelList cancelList;
54  {
55  boost::mutex::scoped_lock lock(_mutex);
56  swap(cancelList, _futureCancelList);
57  }
58  for (FutureCancelList::iterator it = cancelList.begin(), itEnd = cancelList.end();
59  it != itEnd; ++it)
60  {
61  try
62  {
63  it->second();
64  }
65  catch (std::exception& ex)
66  {
67  qiLogWarning("qi.scopedfuturegroup") << "Failed to cancel scoped future: " << ex.what();
68  }
69  catch (...)
70  {
71  qiLogWarning("qi.scopedfuturegroup") << "Failed to cancel scoped future: unknown error.";
72  }
73 
74  }
75  }
76 
78  bool empty() const
79  {
80  boost::mutex::scoped_lock lock(_mutex);
81  return _futureCancelList.empty();
82  }
83 
85  size_t size() const
86  {
87  boost::mutex::scoped_lock lock(_mutex);
88  return _futureCancelList.size();
89  }
90 
91  private:
92  mutable boost::mutex _mutex;
93  using FutureCancelList = boost::container::flat_map< FutureUniqueId, boost::function<void()>>;
94  FutureCancelList _futureCancelList;
95 
96  template<class T>
97  void onFutureFinished(Future<T> future)
98  {
99  boost::mutex::scoped_lock lock(_mutex);
100  _futureCancelList.erase(future.uniqueId());
101  }
102  };
103 }
size_t size() const
Definition: futuregroup.hpp:85
#define qiLogWarning(...)
Log in warning mode.
Definition: log.hpp:101
void swap(::qi::AnyFunction &a,::qi::AnyFunction &b)
Definition: anyfunction.hxx:92
void cancel()
Definition: future_fwd.hpp:314
auto then(FutureCallbackType type, AF &&func) -> qi::Future< typename detail::DecayAsyncResult< AF, qi::Future< T >>::type >
Execute a callback when the future is finished.
Definition: future_fwd.hpp:394
void add(Future< T > future)
Definition: futuregroup.hpp:40
Object tracking by blocking destruction while shared pointers are present.
Definition: trackable.hpp:43
FutureUniqueId uniqueId() const
Definition: future_fwd.hpp:182
bool empty() const
Definition: futuregroup.hpp:78