libqi-api  2.4.3.28
 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 {
20  : boost::noncopyable
21  , public qi::Trackable<ScopedFutureGroup>
22  {
23  public:
26  {}
27 
31  {
32  destroy();
33  cancelAll();
34  }
35 
42  template< class T >
43  void add(Future<T> future)
44  {
45  boost::mutex::scoped_lock lock(_mutex);
46  if (!future.isCancelable())
47  {
48  qiLogVerbose("qi.scopedfuturegroup") << "Trying to add non-cancelable future added to ScopedFutureGroup - future ignored.";
49  return;
50  }
51 
52  _futureCancelList.insert(std::make_pair(future.uniqueId(), qi::bind<void()>(&Future<T>::cancel, future)));
53 
54  // The 2 following lines are necessary because of a compiler bug in VS2010 which is fixed in VS2015 and beyond
55  typedef void (ScopedFutureGroup::* MemFuncType)(Future<T>);
56  MemFuncType onFutureFinishedCallback = &ScopedFutureGroup::onFutureFinished<T>;
57  future.template thenR<void>(onFutureFinishedCallback, this, _1);
58  }
59 
62  void cancelAll()
63  {
64  FutureCancelList cancelList;
65  {
66  boost::mutex::scoped_lock lock(_mutex);
67  swap(cancelList, _futureCancelList);
68  }
69  for (FutureCancelList::iterator it = cancelList.begin(), itEnd = cancelList.end();
70  it != itEnd; ++it)
71  {
72  try
73  {
74  it->second();
75  }
76  catch (std::exception& ex)
77  {
78  qiLogWarning("qi.scopedfuturegroup") << "Failed to cancel scoped future: " << ex.what();
79  }
80  catch (...)
81  {
82  qiLogWarning("qi.scopedfuturegroup") << "Failed to cancel scoped future: unknown error.";
83  }
84 
85  }
86  }
87 
89  bool empty() const
90  {
91  boost::mutex::scoped_lock lock(_mutex);
92  return _futureCancelList.empty();
93  }
94 
96  size_t size() const
97  {
98  boost::mutex::scoped_lock lock(_mutex);
99  return _futureCancelList.size();
100  }
101 
102  private:
103  mutable boost::mutex _mutex;
104  typedef boost::container::flat_map< FutureUniqueId, boost::function<void()> > FutureCancelList;
105  FutureCancelList _futureCancelList;
106 
107  template<class T>
108  void onFutureFinished(Future<T> future)
109  {
110  boost::mutex::scoped_lock lock(_mutex);
111  _futureCancelList.erase(future.uniqueId());
112  }
113  };
114 }
#define qiLogVerbose(...)
Log in verbose mode. This level is not shown by default.
Definition: log.hpp:80
size_t size() const
Definition: futuregroup.hpp:96
boost::shared_ptr< ScopedFutureGroup > lock()
#define qiLogWarning(...)
Log in warning mode.
Definition: log.hpp:102
void swap(::qi::AnyFunction &a,::qi::AnyFunction &b)
Definition: anyfunction.hxx:89
bool isCancelable() const
Definition: future_fwd.hpp:308
void add(Future< T > future)
Definition: futuregroup.hpp:43
Object tracking by blocking destruction while shared pointers are present.
Definition: trackable.hpp:42
FutureUniqueId uniqueId() const
Definition: future_fwd.hpp:174
bool empty() const
Definition: futuregroup.hpp:89