56class AsyncTaskGenerator :
public virtual RobotRaconteur::Generator<RR_INTRUSIVE_PTR<StatusType>, void>,
57 public RR_ENABLE_SHARED_FROM_THIS<AsyncTaskGenerator<StatusType> >
70 AsyncTaskGenerator(
const RR_SHARED_PTR<RobotRaconteur::RobotRaconteurNode>& node, int32_t next_timeout,
71 int32_t watchdog_timeout)
72 : node(node), next_timeout(next_timeout), watchdog_timeout(watchdog_timeout)
78 task_completed =
false;
82 throw RobotRaconteur::InvalidArgumentException(
"next_timeout must be >= 0");
85 if (watchdog_timeout > 0 && watchdog_timeout < next_timeout)
87 throw RobotRaconteur::InvalidArgumentException(
"watchdog_timeout must be >= next_timeout");
91 RR_OVIRTUAL
void AsyncNext(
92 boost::function<
void(
const RR_INTRUSIVE_PTR<StatusType>&,
const RobotRaconteur::RobotRaconteurExceptionPtr&)>
94 int32_t timeout = RR_TIMEOUT_INFINITE) RR_OVERRIDE
97 boost::mutex::scoped_lock lock(this_lock);
102 watchdog_timer->Stop();
104 catch (std::exception&)
106 watchdog_timer.reset();
110 throw RobotRaconteur::OperationAbortedException(
"Operation was aborted");
112 if ((closed && !started) || completed)
114 throw RobotRaconteur::StopIterationException(
"");
121 RR_INTRUSIVE_PTR<StatusType> ret(
new StatusType());
122 ret->action_status = com::robotraconteur::action::ActionStatusCode::running;
125 handler(ret,
nullptr);
131 throw RobotRaconteur::InvalidOperationException(
"Next call already in progress");
136 complete_gen(handler);
143 RR_INTRUSIVE_PTR<StatusType> ret(
new StatusType());
144 ret->action_status = com::robotraconteur::action::ActionStatusCode::running;
147 handler(ret,
nullptr);
151 next_handler = handler;
153 RR_WEAK_PTR<AsyncTaskGenerator<StatusType> > weak_this = this->shared_from_this();
154 next_timer = RobotRaconteur::RobotRaconteurNode::s()->CreateTimer(
155 boost::posix_time::milliseconds(next_timeout),
156 boost::bind(&AsyncTaskGenerator::next_timer_handler, weak_this, RR_BOOST_PLACEHOLDERS(_1)),
true);
158 if (watchdog_timeout > 0)
160 watchdog_timer = RobotRaconteur::RobotRaconteurNode::s()->CreateTimer(
161 boost::posix_time::milliseconds(watchdog_timeout),
162 boost::bind(&AsyncTaskGenerator::watchdog_timer_handler, weak_this, RR_BOOST_PLACEHOLDERS(_1)),
true);
163 watchdog_timer->Start();
167 RR_OVIRTUAL
void AsyncClose(boost::function<
void(
const RobotRaconteur::RobotRaconteurExceptionPtr& err)> handler,
168 int32_t timeout = RR_TIMEOUT_INFINITE) RR_OVERRIDE
171 boost::mutex::scoped_lock lock(this_lock);
172 if (closed || aborted)
187 RR_OVIRTUAL
void AsyncAbort(boost::function<
void(
const RobotRaconteur::RobotRaconteurExceptionPtr& err)> handler,
188 int32_t timeout = RR_TIMEOUT_INFINITE) RR_OVERRIDE
191 boost::mutex::scoped_lock lock(this_lock);
192 if (closed || aborted)
207 RR_OVIRTUAL RR_INTRUSIVE_PTR<StatusType> Next() RR_OVERRIDE
210 throw RobotRaconteur::NotImplementedException(
"Not implemented");
212 RR_OVIRTUAL
void Close() RR_OVERRIDE
215 throw RobotRaconteur::NotImplementedException(
"Not implemented");
217 RR_OVIRTUAL
void Abort() RR_OVERRIDE
220 throw RobotRaconteur::NotImplementedException(
"Not implemented");
232 virtual void SetResult(RR_INTRUSIVE_PTR<StatusType>& result)
234 boost::mutex::scoped_lock lock(this_lock);
237 this->result = result;
251 boost::mutex::scoped_lock lock(this_lock);
254 this->exception_result = exp;
260 task_completed =
true;
261 auto h = next_handler;
262 next_handler.clear();
269 catch (std::exception&)
278 boost::function<
void(
const RR_INTRUSIVE_PTR<StatusType>&,
const RobotRaconteur::RobotRaconteurExceptionPtr&)>
283 if (exception_result)
285 auto exp = exception_result;
286 exception_result.reset();
287 handler(
nullptr, exp);
290 RR_INTRUSIVE_PTR<StatusType> ret = result;
292 handler(ret,
nullptr);
304 boost::mutex::scoped_lock lock(this_lock);
305 if (task_completed || aborted || closed)
316 catch (std::exception&)
348 virtual void FillStatus(RR_INTRUSIVE_PTR<StatusType>& status) {}
350 static void next_timer_handler(RR_WEAK_PTR<AsyncTaskGenerator> weak_this,
const RobotRaconteur::TimerEvent& evt)
353 RR_SHARED_PTR<AsyncTaskGenerator> shared_this = weak_this.lock();
356 boost::mutex::scoped_lock lock(shared_this->this_lock);
357 shared_this->do_send_update();
360 void do_send_update()
362 auto h = next_handler;
363 next_handler.clear();
366 RR_INTRUSIVE_PTR<StatusType> ret(
new StatusType());
367 ret->action_status = com::robotraconteur::action::ActionStatusCode::running;
374 static void watchdog_timer_handler(RR_WEAK_PTR<AsyncTaskGenerator> weak_this,
const RobotRaconteur::TimerEvent& evt)
376 RR_SHARED_PTR<AsyncTaskGenerator> shared_this = weak_this.lock();
381 boost::mutex::scoped_lock lock(shared_this->this_lock);
382 if (shared_this->task_completed)
384 shared_this->aborted =
true;
385 shared_this->AbortRequested();
388 RR_WEAK_PTR<RobotRaconteur::RobotRaconteurNode> node;
389 RR_SHARED_PTR<RobotRaconteur::Timer> next_timer;
390 RR_SHARED_PTR<RobotRaconteur::Timer> watchdog_timer;
397 int32_t next_timeout;
398 int32_t watchdog_timeout;
399 boost::mutex this_lock;
400 boost::function<void(
const RR_INTRUSIVE_PTR<StatusType>&,
const RobotRaconteur::RobotRaconteurExceptionPtr&)>
402 RR_INTRUSIVE_PTR<StatusType> result;
403 RR_SHARED_PTR<RobotRaconteurException> exception_result;