@@ -408,6 +408,76 @@ Executor::execute_any_executable(AnyExecutable & any_exec)
408408 }
409409}
410410
411+ template <typename Function>
412+ void execute_guarded (
413+ const Function & fun,
414+ const std::function<void (const std::exception & e)> & exception_handler)
415+ {
416+ try {
417+ fun ();
418+ } catch (const std::exception & e) {
419+ RCLCPP_ERROR_STREAM (
420+ rclcpp::get_logger (" rclcpp" ),
421+ " Exception while spinning : " << e.what ());
422+
423+ exception_handler (e);
424+ }
425+ }
426+
427+ void
428+ Executor::execute_any_executable (
429+ AnyExecutable & any_exec,
430+ const std::function<void (const std::exception & e)> & exception_handler)
431+ {
432+ if (!spinning.load ()) {
433+ return ;
434+ }
435+
436+ if (any_exec.timer ) {
437+ TRACETOOLS_TRACEPOINT (
438+ rclcpp_executor_execute,
439+ static_cast <const void *>(any_exec.timer ->get_timer_handle ().get ()));
440+ execute_guarded ([&any_exec]() {
441+ execute_timer (any_exec.timer , any_exec.data );
442+ }, exception_handler);
443+ }
444+ if (any_exec.subscription ) {
445+ TRACETOOLS_TRACEPOINT (
446+ rclcpp_executor_execute,
447+ static_cast <const void *>(any_exec.subscription ->get_subscription_handle ().get ()));
448+ execute_guarded (
449+ [&any_exec]() {
450+ execute_subscription (any_exec.subscription );
451+ }, exception_handler);
452+ }
453+ if (any_exec.service ) {
454+ execute_guarded ([&any_exec]() {execute_service (any_exec.service );}, exception_handler);
455+ }
456+ if (any_exec.client ) {
457+ execute_guarded ([&any_exec]() {execute_client (any_exec.client );}, exception_handler);
458+ }
459+ if (any_exec.waitable ) {
460+ execute_guarded ([&any_exec]() {
461+ const std::shared_ptr<void > & const_data = any_exec.data ;
462+ any_exec.waitable ->execute (const_data);
463+ }, exception_handler);
464+ }
465+ // Reset the callback_group, regardless of type
466+ if (any_exec.callback_group ) {
467+ any_exec.callback_group ->can_be_taken_from ().store (true );
468+ }
469+ // Wake the wait, because it may need to be recalculated or work that
470+ // was previously blocked is now available.
471+ try {
472+ interrupt_guard_condition_->trigger ();
473+ } catch (const rclcpp::exceptions::RCLError & ex) {
474+ throw std::runtime_error (
475+ std::string (
476+ " Failed to trigger guard condition from execute_any_executable: " ) + ex.what ());
477+ }
478+ }
479+
480+
411481template <typename Taker, typename Handler>
412482static
413483void
0 commit comments