- Aldebaran documentation |
- C++ Libraries |
- index

libqi-api 2.8.7.4

- Main Page
- Related Pages
- Namespaces
- Classes
- Files
- Examples

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
async.hxx
Go to the documentation of this file.
1 #pragma once
2
7 #ifndef _QI_DETAIL_ASYNC_HXX_
8 #define _QI_DETAIL_ASYNC_HXX_
9
10 #include <qi/async.hpp>
11 #include <functional>
12
13 namespace qi
14 {
15 namespace detail
16 {
17 template <typename F>
18 inline auto asyncMaybeActor(F&& cb, qi::Duration delay) ->
19 typename std::enable_if<detail::IsAsyncBind<F>::value, typename std::decay<decltype(cb())>::type>::type
20 {
21 if (delay != qi::Duration::zero())
22 return qi::getEventLoop()->asyncDelay(cb, delay).unwrap();
23 else
24 return cb();
25 }
26
27 template <typename F>
28 inline auto asyncMaybeActor(F&& cb, qi::Duration delay) ->
29 typename std::enable_if<!detail::IsAsyncBind<F>::value,
30 qi::Future<typename std::decay<decltype(cb())>::type>>::type
31 {
32 return qi::getEventLoop()->asyncDelay(cb, delay);
33 }
34
35 template <typename F>
36 inline auto asyncMaybeActor(F&& cb, qi::SteadyClockTimePoint timepoint) ->
37 typename std::enable_if<detail::IsAsyncBind<F>::value, typename std::decay<decltype(cb())>::type>::type
38 {
39 return qi::getEventLoop()->asyncAt(cb, timepoint).unwrap();
40 }
41 template <typename F>
42 inline auto asyncMaybeActor(F&& cb, qi::SteadyClockTimePoint timepoint) ->
43 typename std::enable_if<!detail::IsAsyncBind<F>::value,
44 qi::Future<typename std::decay<decltype(cb())>::type>>::type
45 {
46 return qi::getEventLoop()->asyncAt(cb, timepoint);
47 }
48
49 // this function is used by qilang generation to call something regardless of if it's an actor or not
50 // it is very specific to qilang's generated code, I don't think it's a good idea to use it elsewhere
51 // this function may or may not return a future (the other overload does not)
52 template <typename F, typename Arg0, typename... Args>
53 auto invokeMaybeActor(F&& cb, Arg0* arg0, Args&&... args) ->
54 typename std::enable_if<std::is_base_of<Actor, typename std::decay<Arg0>::type>::value,
55 decltype(tryUnwrap(arg0->async(boost::bind(cb, arg0, std::forward<Args>(args)...)), 0))>::type
56 {
57 // this is an actor, we must async to strand the call
58 return tryUnwrap(arg0->async(boost::bind(cb, arg0, std::forward<Args>(args)...)), 0);
59 }
60 template <typename F, typename Arg0, typename... Args>
61 auto invokeMaybeActor(F&& cb, Arg0* arg0, Args&&... args) ->
62 typename std::enable_if<!std::is_base_of<Actor, typename std::decay<Arg0>::type>::value,
63 typename std::decay<decltype((arg0->*cb)(std::forward<Args>(args)...))>::type>::type
64 {
65 QI_ASSERT(arg0 && "the pointer on which the member is called is null");
66 return (arg0->*cb)(std::forward<Args>(args)...);
67 }
68 } // detail
69
72 template<typename R>
73 QI_API_DEPRECATED_MSG(Use 'asyncDelay' instead)
74 inline Future<R> async(boost::function<R()> callback, uint64_t usDelay)
75 {
76 return qi::getEventLoop()->asyncDelay(callback, qi::MicroSeconds(usDelay));
77 }
78 template<typename R>
79 QI_API_DEPRECATED_MSG(Use 'asyncDelay' instead)
80 inline Future<R> async(boost::function<R()> callback, qi::Duration delay)
81 {
82 return qi::getEventLoop()->asyncDelay(callback, delay);
83 }
84 template<typename R>
85 QI_API_DEPRECATED_MSG(Use 'asyncAt' instead)
86 inline Future<R> async(boost::function<R()> callback, qi::SteadyClockTimePoint timepoint)
87 {
88 return qi::getEventLoop()->asyncAt(callback, timepoint);
89 }
90 template<typename R>
91 QI_API_DEPRECATED_MSG(Use 'async' without explicit return type template arguement instead)
92 inline Future<R> async(detail::Function<R()> callback)
93 {
94 return qi::getEventLoop()->async(callback);
95 }
96
97 #ifdef DOXYGEN
98 template<typename R, typename Func, typename ArgTrack>
100 QI_API_DEPRECATED qi::Future<R> async(const Func& f, const ArgTrack& toTrack, ...);
101 #else
102 #define genCall(n, ATYPEDECL, ATYPES, ADECL, AUSE, comma) \
103 template <typename R, typename AF, typename ARG0 comma ATYPEDECL> \
104 inline QI_API_DEPRECATED Future<R> async(const AF& fun, const ARG0& arg0 comma ADECL, qi::Duration delay = qi::Duration(0)) \
105 { \
106 return detail::asyncMaybeActor(qi::bind(fun, arg0 comma AUSE), delay); \
107 } \
108 template <typename R, typename AF, typename ARG0 comma ATYPEDECL> \
109 inline QI_API_DEPRECATED Future<R> async(const AF& fun, const ARG0& arg0 comma ADECL, qi::SteadyClockTimePoint timepoint) \
110 { \
111 return detail::asyncMaybeActor(qi::bind(fun, arg0 comma AUSE), timepoint); \
112 }
113 QI_GEN(genCall)
114 #undef genCall
115 #endif
116
117 namespace detail
118 {
119 template<typename T>
120 void tryCancel(Future<T>& fut, const char* errorMsg)
121 {
122 try
123 {
124 // This condition is racy, but the goal is to avoid useless logs
125 // (in the catch clauses).
126 if (fut.isRunning())
127 {
128 fut.cancel();
129 }
130 }
131 catch (const std::runtime_error& e)
132 {
133 qiLogVerbose("qi.Future") << errorMsg << "detail=" << e.what();
134 }
135 catch (...)
136 {
137 qiLogVerbose("qi.Future") << errorMsg << "No detail.";
138 }
139 }
140 }
141
146 template<typename T, typename Duration>
147 Future<T> cancelOnTimeout(Future<T> fut, Duration timeout)
148 {
149 auto cancelFut = asyncDelay(
150 [=]() mutable {
151 detail::tryCancel(fut, "cancelOnTimeout: timeout task failed to cancel the running task: ");
152 },
153 timeout);
154 fut.then([=](const Future<T>&) mutable {
155 detail::tryCancel(cancelFut, "cancelOnTimeout: running task failed to cancel the timeout task");
156 });
157 return fut;
158 }
159
160 } // qi
161 #endif // _QI_DETAIL_ASYNC_HXX_
qi::asyncDelay
auto asyncDelay(F &&callback, qi::Duration delay) -> decltype(detail::asyncMaybeActor(std::forward< F >(callback), delay))
Definition: async.hpp:46
qi::MicroSeconds
DurationType< int64_t, boost::micro > MicroSeconds
Definition: clock.hpp:26
qi::Future
Definition: executioncontext.hpp:20
qi::SteadyClockTimePoint
SteadyClock::time_point SteadyClockTimePoint
Steady clock time point.
Definition: clock.hpp:211
qiLogVerbose
#define qiLogVerbose(...)
Log in verbose mode. This level is not shown by default.
Definition: log.hpp:87
QI_ASSERT
#define QI_ASSERT(expr__)
Definition: assert.hpp:27
qi::detail::tryCancel
void tryCancel(Future< T > &fut, const char *errorMsg)
Definition: async.hxx:120
qi::EventLoop::async
Future< R > async(const boost::function< R()> &callback, uint64_t usDelay)
Calls given function once after given delay in microseconds.
Definition: eventloop.hxx:19
qi::ExecutionContext::asyncDelay
qi::Future< R > asyncDelay(F &&callback, qi::Duration delay, ExecutionOptions options=defaultExecutionOptions())
call a callback asynchronously to be executed in delay
qi::Future::then
auto then(FutureCallbackType type, F &&func) -> Future< typename std::result_of< F(Future< T >)>::type >
Execute a callback when the future is finished.
Definition: future_fwd.hpp:453
qi::Duration
NanoSeconds Duration
Definition: clock.hpp:32
qi::detail::asyncMaybeActor
auto asyncMaybeActor(F &&cb, qi::Duration delay) -> typename std::enable_if< detail::IsAsyncBind< F >::value, typename std::decay< decltype(cb())>::type >::type
Definition: async.hxx:18
genCall
#define genCall(n, ATYPEDECL, ATYPES, ADECL, AUSE, comma)
Definition: session.hpp:175
QI_API_DEPRECATED_MSG
#define QI_API_DEPRECATED_MSG(msg__)
Compiler flags to mark a function as deprecated. It will generate a compiler warning.
Definition: macro.hpp:55
qi::async
auto async(F &&callback) -> decltype(asyncDelay(std::forward< F >(callback), qi::Duration(0)))
Definition: async.hpp:53
qi::detail::tryUnwrap
T tryUnwrap(T anything)
Definition: futureunwrap.hpp:19
qi::Future::isRunning
bool isRunning() const
Definition: future_fwd.hpp:330
qi::Future::cancel
void cancel()
Definition: future_fwd.hpp:383
qi::getEventLoop
EventLoop * getEventLoop()
Returns the global eventloop, created on demand on first call.
qi::ExecutionContext::asyncAt
qi::Future< R > asyncAt(F &&callback, qi::SteadyClockTimePoint tp, ExecutionOptions options=defaultExecutionOptions())
call a callback asynchronously to be executed on tp
async.hpp
QI_API_DEPRECATED
#define QI_API_DEPRECATED
Compiler flags to mark a function as deprecated. It will generate a compiler warning.
Definition: macro.hpp:41
qi::detail::invokeMaybeActor
auto invokeMaybeActor(F &&cb, Arg0 *arg0, Args &&...args) -> typename std::enable_if< std::is_base_of< Actor, typename std::decay< Arg0 >::type >::value, decltype(tryUnwrap(arg0->async(boost::bind(cb, arg0, std::forward< Args >(args)...)), 0))>::type
Definition: async.hxx:53
qi::uint64_t
uint64_t uint64_t
Definition: types.hpp:66
qi::bind
std::enable_if< std::is_function< RF >::value, boost::function< RF > >::type bind(AF &&fun, Arg0 &&arg0, Args &&...args)
Definition: trackable.hxx:308
QI_GEN
#define QI_GEN(f)
Definition: preproc.hpp:476
qi::cancelOnTimeout
Future< T > cancelOnTimeout(Future< T > fut, Duration timeout)
Definition: async.hxx:147