23 #include "rclcpp/executor.hpp"
24 #include "rclcpp/macros.hpp"
25 #include "rclcpp/utilities.hpp"
26 #include "rclcpp/visibility_control.hpp"
33 namespace cbg_executor
36 struct RegisteredEntityCache;
38 struct GlobalWeakExecutableCache;
61 size_t number_of_threads = 0,
62 std::chrono::nanoseconds timeout = std::chrono::nanoseconds(-1));
70 const rclcpp::CallbackGroup::SharedPtr & group_ptr,
71 const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr & node_ptr,
72 bool notify =
true)
override;
75 std::vector<rclcpp::CallbackGroup::WeakPtr>
79 std::vector<rclcpp::CallbackGroup::WeakPtr>
83 std::vector<rclcpp::CallbackGroup::WeakPtr>
89 const rclcpp::CallbackGroup::SharedPtr & group_ptr,
90 bool notify =
true)
override;
95 const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr & node_ptr,
96 bool notify =
true)
override;
104 add_node(
const std::shared_ptr<rclcpp::Node> & node_ptr,
bool notify =
true)
override;
109 const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr & node_ptr,
110 bool notify =
true)
override;
118 remove_node(
const std::shared_ptr<rclcpp::Node> & node_ptr,
bool notify =
true)
override;
121 void add_callback_group_only(
const rclcpp::CallbackGroup::SharedPtr & group_ptr);
141 spin(
const std::function<
void(
const std::exception &)> & exception_handler);
145 spin_once(std::chrono::nanoseconds timeout = std::chrono::nanoseconds(-1))
override;
149 spin_some(std::chrono::nanoseconds max_duration = std::chrono::nanoseconds(0))
override;
156 std::chrono::nanoseconds max_duration,
157 bool recollect_if_no_work_available);
161 spin_all(std::chrono::nanoseconds max_duration)
override;
174 get_number_of_threads()
const;
182 template<
typename FutureT,
typename TimeRepT =
int64_t,
typename TimeT = std::milli>
184 spin_until_future_complete(
185 const FutureT & future,
186 std::chrono::duration<TimeRepT, TimeT> timeout = std::chrono::duration<TimeRepT, TimeT>(-1))
193 std::future_status status = future.wait_for(std::chrono::seconds(0));
194 if (status == std::future_status::ready) {
195 return FutureReturnCode::SUCCESS;
198 auto end_time = std::chrono::steady_clock::now();
199 std::chrono::nanoseconds timeout_ns = std::chrono::duration_cast<std::chrono::nanoseconds>(
201 if (timeout_ns > std::chrono::nanoseconds::zero()) {
202 end_time += timeout_ns;
204 std::chrono::nanoseconds timeout_left = timeout_ns;
206 if (spinning.exchange(
true)) {
207 throw std::runtime_error(
"spin_until_future_complete() called while already spinning");
209 RCPPUTILS_SCOPE_EXIT(
210 this->spinning.store(
false);
211 this->cancel_requested_.store(
false); );
213 return FutureReturnCode::INTERRUPTED;
217 spin_once_internal(timeout_left);
220 status = future.wait_for(std::chrono::seconds(0));
221 if (status == std::future_status::ready) {
222 return FutureReturnCode::SUCCESS;
225 if (timeout_ns < std::chrono::nanoseconds::zero()) {
229 auto now = std::chrono::steady_clock::now();
230 if (now >= end_time) {
231 return FutureReturnCode::TIMEOUT;
234 timeout_left = std::chrono::duration_cast<std::chrono::nanoseconds>(end_time - now);
238 return FutureReturnCode::INTERRUPTED;
250 run(
size_t this_thread_number,
bool block_initially);
255 size_t this_thread_number,
256 const std::function<
void(
const std::exception &)> & exception_handler);
264 std::unique_ptr<cbg_executor::CBGScheduler> scheduler;
274 CallbackGroup::WeakPtr callback_group;
276 std::unique_ptr<cbg_executor::RegisteredEntityCache> registered_entities;
288 const std::chrono::time_point<std::chrono::steady_clock> & stop_time);
290 void unregister_event_callbacks(
const rclcpp::CallbackGroup::SharedPtr & cbg)
const;
293 void remove_all_nodes_and_callback_groups();
295 void sync_callback_groups();
301 void trigger_callback_group_sync();
304 void spin_once_internal(std::chrono::nanoseconds timeout);
308 std::mutex added_callback_groups_mutex_;
309 std::vector<rclcpp::CallbackGroup::WeakPtr> added_callback_groups;
311 std::mutex added_nodes_mutex_;
312 std::vector<node_interfaces::NodeBaseInterface::WeakPtr> added_nodes;
314 std::mutex callback_groups_mutex;
316 std::vector<CallbackGroupData> callback_groups;
318 size_t number_of_threads_;
320 std::chrono::nanoseconds next_exec_timeout_;
322 std::atomic_bool needs_callback_group_resync =
false;
330 std::atomic_bool spinning;
333 bool in_shutdown =
false;
336 std::shared_ptr<rclcpp::GuardCondition> interrupt_guard_condition_;
339 std::shared_ptr<rclcpp::GuardCondition> shutdown_guard_condition_;
345 std::shared_ptr<rclcpp::Context> context_;
347 std::unique_ptr<cbg_executor::TimerManager> timer_manager;
351 std::unique_ptr<cbg_executor::GlobalWeakExecutableCache> global_executable_cache;
354 std::unique_ptr<cbg_executor::GlobalWeakExecutableCache> nodes_executable_cache;
Coordinate the order and timing of available communication tasks.
static RCLCPP_PUBLIC void execute_timer(const rclcpp::TimerBase::SharedPtr &timer, const std::shared_ptr< void > &data_ptr)
Run timer executable.
static RCLCPP_PUBLIC void execute_client(const rclcpp::ClientBase::SharedPtr &client)
Run service client executable.
static RCLCPP_PUBLIC void execute_service(const rclcpp::ServiceBase::SharedPtr &service)
Run service server executable.
std::atomic_bool cancel_requested_
Tracks a pending cancel request that has not yet been consumed by a spin.
static RCLCPP_PUBLIC void execute_subscription(const rclcpp::SubscriptionBase::SharedPtr &subscription)
Run subscription executable.
Node is the single point of entry for creating publishers and subscribers.
RCLCPP_PUBLIC std::vector< rclcpp::CallbackGroup::WeakPtr > get_all_callback_groups() override
Get callback groups that belong to executor.
RCLCPP_PUBLIC void spin_once(std::chrono::nanoseconds timeout=std::chrono::nanoseconds(-1)) override
Collect work once and execute the next available work, optionally within a duration.
RCLCPP_PUBLIC void spin(const std::function< void(const std::exception &)> &exception_handler)
RCLCPP_PUBLIC void add_callback_group(const rclcpp::CallbackGroup::SharedPtr &group_ptr, const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr &node_ptr, bool notify=true) override
Add a callback group to an executor.
RCLCPP_PUBLIC void spin_some(std::chrono::nanoseconds max_duration=std::chrono::nanoseconds(0)) override
Collect work once and execute all available work, optionally within a max duration.
RCLCPP_PUBLIC void add_node(const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr &node_ptr, bool notify=true) override
Add a node to the executor.
bool execute_previous_ready_executables_until(const std::chrono::time_point< std::chrono::steady_clock > &stop_time)
RCLCPP_PUBLIC EventsCBGExecutor(const rclcpp::ExecutorOptions &options=rclcpp::ExecutorOptions(), size_t number_of_threads=0, std::chrono::nanoseconds timeout=std::chrono::nanoseconds(-1))
RCLCPP_PUBLIC void spin_all(std::chrono::nanoseconds max_duration) override
Collect and execute work repeatedly within a duration or until no more work is available.
RCLCPP_PUBLIC void remove_node(const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr &node_ptr, bool notify=true) override
Remove a node from the executor.
RCLCPP_PUBLIC bool collect_and_execute_ready_events(std::chrono::nanoseconds max_duration, bool recollect_if_no_work_available)
RCLCPP_PUBLIC void cancel() override
Cancel any running spin* function, causing it to return.
RCLCPP_PUBLIC std::vector< rclcpp::CallbackGroup::WeakPtr > get_manually_added_callback_groups() override
Get callback groups that belong to executor.
RCLCPP_PUBLIC std::vector< rclcpp::CallbackGroup::WeakPtr > get_automatically_added_callback_groups_from_nodes() override
Get callback groups that belong to executor.
RCLCPP_PUBLIC void spin() override
RCLCPP_PUBLIC void remove_callback_group(const rclcpp::CallbackGroup::SharedPtr &group_ptr, bool notify=true) override
Remove a callback group from the executor.
Versions of rosidl_typesupport_cpp::get_message_type_support_handle that handle adapted types.
RCLCPP_PUBLIC bool ok(const rclcpp::Context::SharedPtr &context=rclcpp::contexts::get_global_default_context())
Check rclcpp's status.
FutureReturnCode
Return codes to be used with spin_until_future_complete.
Options to be passed to the executor constructor.