libqi-api  release-2.5.3-2016-11-18
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
eventloop.hpp
Go to the documentation of this file.
1 #pragma once
2 /*
3 ** Copyright (C) 2012 Aldebaran Robotics
4 ** See COPYING for the license
5 */
6 
7 #ifndef _QI_EVENTLOOP_HPP_
8 # define _QI_EVENTLOOP_HPP_
9 
10 # ifdef _MSC_VER
11 # pragma warning( disable: 4503 ) // decorated name length
12 # endif
13 
14 # include <boost/shared_ptr.hpp>
15 # include <boost/function.hpp>
16 
17 # include <qi/types.hpp>
18 # include <qi/api.hpp>
19 # include <qi/clock.hpp>
21 
22 # ifdef _MSC_VER
23 # pragma warning( push )
24 # pragma warning( disable: 4251 )
25 # pragma warning( disable: 4996 ) // TODO: Reactivate this warning once msvc stop triggerring a warning on overloading a deprecated function
26 # endif
27 
28 namespace boost {
29  namespace asio {
30  class io_service;
31 }}
32 
33 namespace qi
34 {
35  template<typename T> class Future;
36 
37  class EventLoopPrivate;
43  {
44  public:
51  EventLoop(const std::string& name = "eventloop");
52 
54  ~EventLoop();
59  bool isInThisContext() override;
64  void start(int nthreads = 0);
65 
67  void join();
69  void stop();
74  void setEmergencyCallback(boost::function<void()> cb);
75 
80  void setMaxThreads(unsigned int max);
81 
83  void *nativeHandle();
84 
85  // DEPRECATED
87 
94  template<typename R>
95  QI_API_DEPRECATED_MSG(Use 'asyncDelay' instead)
96  Future<R> async(const boost::function<R()>& callback, uint64_t usDelay);
97  QI_API_DEPRECATED_MSG(Use 'asyncDelay' instead)
98  Future<void> async(const boost::function<void()>& callback, uint64_t usDelay)
99  {
100  return asyncDelayImpl(callback, qi::MicroSeconds(usDelay));
101  }
102  QI_API_DEPRECATED_MSG(Use 'asyncDelay' instead)
103  Future<void> async(const boost::function<void()>& callback, qi::Duration delay) override
104  {
105  return asyncDelayImpl(callback, delay);
106  }
107  QI_API_DEPRECATED_MSG(Use 'asyncAt' instead)
108  Future<void> async(
109  const boost::function<void()>& callback, qi::SteadyClockTimePoint timepoint) override
110  {
111  return asyncAt(callback, timepoint);
112  }
113 
116 
122  QI_API_DEPRECATED_MSG(Use 'asyncDelay' instead)
123  void post(const boost::function<void ()>& callback, uint64_t usDelay)
124  {
125  postDelayImpl(callback, qi::MicroSeconds(usDelay));
126  }
127  QI_API_DEPRECATED_MSG(Use 'asyncDelay' instead)
128  void post(const boost::function<void ()>& callback, qi::Duration delay)
129  {
130  postDelayImpl(callback, delay);
131  }
132  QI_API_DEPRECATED_MSG(Use 'asyncAt' instead)
133  void post(const boost::function<void ()>& callback, qi::SteadyClockTimePoint timepoint);
134  // END DEPRECATED
135 
137 
146  Future<void> monitorEventLoop(EventLoop* helper, uint64_t maxUsDelay);
147 
148  private:
149  EventLoopPrivate *_p;
150  std::string _name;
151 
152  void postImpl(boost::function<void()> callback) override
153  {
154  postDelayImpl(callback, qi::Duration(0));
155  }
156  void postDelayImpl(boost::function<void()> callback, qi::Duration delay);
157  qi::Future<void> asyncAtImpl(boost::function<void()> cb, qi::SteadyClockTimePoint tp) override;
158  qi::Future<void> asyncDelayImpl(boost::function<void()> cb, qi::Duration delay) override;
159  };
160 
162  QI_API EventLoop* getEventLoop();
163 
164  namespace detail
165  {
166  template <typename F>
167  inline auto asyncMaybeActor(F&& cb, qi::Duration delay) ->
168  typename std::enable_if<detail::IsAsyncBind<F>::value, typename std::decay<decltype(cb())>::type>::type;
169  template <typename F>
170  inline auto asyncMaybeActor(F&& cb, qi::Duration delay) ->
171  typename std::enable_if<!detail::IsAsyncBind<F>::value,
173  template <typename F>
174  inline auto asyncMaybeActor(F&& cb, qi::SteadyClockTimePoint timepoint) ->
175  typename std::enable_if<detail::IsAsyncBind<F>::value, typename std::decay<decltype(cb())>::type>::type;
176  template <typename F>
177  inline auto asyncMaybeActor(F&& cb, qi::SteadyClockTimePoint timepoint) ->
178  typename std::enable_if<!detail::IsAsyncBind<F>::value,
180  }
181 
184  template<typename R>
185  QI_API_DEPRECATED_MSG(Use 'asyncDelay' instead)
186  inline Future<R> async(boost::function<R()> callback, uint64_t usDelay)
187  {
188  return qi::getEventLoop()->asyncDelay(callback, qi::MicroSeconds(usDelay));
189  }
190  template<typename R>
191  QI_API_DEPRECATED_MSG(Use 'asyncDelay' instead)
192  inline Future<R> async(boost::function<R()> callback, qi::Duration delay)
193  {
194  return qi::getEventLoop()->asyncDelay(callback, delay);
195  }
196  template<typename R>
197  QI_API_DEPRECATED_MSG(Use 'asyncAt' instead)
198  inline Future<R> async(boost::function<R()> callback, qi::SteadyClockTimePoint timepoint)
199  {
200  return qi::getEventLoop()->asyncAt(callback, timepoint);
201  }
202  template<typename R>
203  QI_API_DEPRECATED_MSG(Use 'async' without explicit return type template arguement instead)
204  inline Future<R> async(detail::Function<R()> callback)
205  {
206  return qi::getEventLoop()->async(callback);
207  }
208 
209  template <typename F>
210  inline auto asyncDelay(F&& callback, qi::Duration delay)
211  -> decltype(detail::asyncMaybeActor(std::forward<F>(callback), delay))
212  {
213  return detail::asyncMaybeActor(std::forward<F>(callback), delay);
214  }
215  template <typename F>
216  inline auto asyncAt(F&& callback, qi::SteadyClockTimePoint timepoint)
217  -> decltype(qi::getEventLoop()->asyncAt(std::forward<F>(callback), timepoint))
218  {
219  return qi::getEventLoop()->asyncAt(std::forward<F>(callback), timepoint);
220  }
221  template <typename F>
222  inline auto async(F&& callback)
223  -> decltype(asyncDelay(std::forward<F>(callback), qi::Duration(0)))
224  {
225  return asyncDelay(std::forward<F>(callback), qi::Duration(0));
226  }
227 
228 #ifdef DOXYGEN
229  template<typename R, typename Func, typename ArgTrack>
231  QI_API_DEPRECATED qi::Future<R> async(const Func& f, const ArgTrack& toTrack, ...);
232 #else
233 #define genCall(n, ATYPEDECL, ATYPES, ADECL, AUSE, comma) \
234  template <typename R, typename AF, typename ARG0 comma ATYPEDECL> \
235  inline QI_API_DEPRECATED Future<R> async(const AF& fun, const ARG0& arg0 comma ADECL, qi::Duration delay = qi::Duration(0)) \
236  { \
237  return detail::asyncMaybeActor(qi::bind(fun, arg0 comma AUSE), delay); \
238  } \
239  template <typename R, typename AF, typename ARG0 comma ATYPEDECL> \
240  inline QI_API_DEPRECATED Future<R> async(const AF& fun, const ARG0& arg0 comma ADECL, qi::SteadyClockTimePoint timepoint) \
241  { \
242  return detail::asyncMaybeActor(qi::bind(fun, arg0 comma AUSE), timepoint); \
243  }
244  QI_GEN(genCall)
245 #undef genCall
246 #endif
247 
252  QI_API void startEventLoop(int nthread);
253 
258  QI_API boost::asio::io_service& getIoService();
259 
260  namespace detail {
261  /* when throw this thread will stop a thread of the eventloop
262  */
264  };
265  };
266 }
267 
268 # ifdef _MSC_VER
269 # pragma warning( pop )
270 # endif
271 
272 # include <qi/detail/eventloop.hxx>
273 #endif // _QI_EVENTLOOP_HPP_
auto asyncDelay(F &&callback, qi::Duration delay) -> decltype(detail::asyncMaybeActor(std::forward< F >(callback), delay))
Definition: eventloop.hpp:210
DurationType< int64_t, boost::micro > MicroSeconds
Definition: clock.hpp:26
#define QI_API
Definition: api.hpp:33
SteadyClock::time_point SteadyClockTimePoint
Steady clock time point.
Definition: clock.hpp:211
Class to handle eventloop. <includename>qi/eventloop.hpp</includename> .
Definition: eventloop.hpp:42
virtual qi::Future< void > async(const boost::function< void()> &callback, qi::SteadyClockTimePoint tp)=0
Future< R > async(const boost::function< R()> &callback, uint64_t usDelay)
Call given function once after given delay in microseconds.
Definition: eventloop.hxx:21
dll import/export and compiler message
auto asyncDelay(F &&callback, qi::Duration delay) -> qi::Future< typename std::decay< decltype(callback())>::type >
call a callback asynchronously to be executed in delay
NanoSeconds Duration
Definition: clock.hpp:32
void startEventLoop(int nthread)
Start the eventloop with nthread threads. No-op if already started.
typename detail::FunctionImpl< A >::type Function
Definition: traits.hpp:133
auto asyncMaybeActor(F &&cb, qi::Duration delay) -> typename std::enable_if< detail::IsAsyncBind< F >::value, typename std::decay< decltype(cb())>::type >::type
Definition: eventloop.hxx:30
boost::asio::io_service & getIoService()
Get the io_service used by the global event loop.
Future< R > async(boost::function< R()> callback, uint64_t usDelay)
Definition: eventloop.hpp:186
void post(F &&callback)
post a callback to be executed as soon as possible
#define genCall(n, ATYPEDECL, ATYPES, ADECL, AUSE, comma)
Definition: session.hpp:107
#define QI_API_DEPRECATED_MSG(msg__)
Compiler flags to mark a function as deprecated. It will generate a compiler warning.
Definition: macro.hpp:53
EventLoop * getEventLoop()
Return the global eventloop, created on demand on first call.
auto asyncAt(F &&callback, qi::SteadyClockTimePoint timepoint) -> decltype(qi::getEventLoop() ->asyncAt(std::forward< F >(callback), timepoint))
Definition: eventloop.hpp:216
auto asyncAt(F &&callback, qi::SteadyClockTimePoint tp) -> qi::Future< typename std::decay< decltype(callback())>::type >
call a callback asynchronously to be executed on tp
#define QI_API_DEPRECATED
Compiler flags to mark a function as deprecated. It will generate a compiler warning.
Definition: macro.hpp:39
uint64_t uint64_t
Definition: types.hpp:66
#define QI_GEN(f)
Definition: preproc.hpp:476