22 #include <rclcpp/callback_group.hpp>
23 #include "global_event_id_provider.hpp"
29 namespace cbg_executor
36 rclcpp::Waitable::WeakPtr waitable;
37 int internal_event_type;
41 return waitable.expired();
48 : callback(std::move(callback))
52 std::function<void()> callback;
63 : scheduler(scheduler) {}
73 virtual std::function<void(
size_t)> get_ready_callback_for_entity(
74 const rclcpp::SubscriptionBase::WeakPtr & entity) = 0;
75 virtual std::function<void(std::function<
void()> executed_callback)>
76 get_ready_callback_for_entity(
const rclcpp::TimerBase::WeakPtr & entity) = 0;
77 virtual std::function<void(
size_t)> get_ready_callback_for_entity(
78 const rclcpp::ClientBase::WeakPtr & entity) = 0;
79 virtual std::function<void(
size_t)> get_ready_callback_for_entity(
80 const rclcpp::ServiceBase::WeakPtr & entity) = 0;
81 virtual std::function<void(
size_t,
82 int)> get_ready_callback_for_entity(
const rclcpp::Waitable::WeakPtr & entity) = 0;
83 virtual std::function<void(
size_t)> get_ready_callback_for_entity(
92 std::lock_guard l(ready_mutex);
121 template<
typename add_fun>
125 std::lock_guard l(ready_mutex);
129 if(not_ready || !idle) {
142 void mark_as_skipped()
159 std::mutex ready_mutex;
163 bool not_ready =
false;
172 std::function<void()> execute_function;
183 : sync_function(sync_function) {}
191 CallbackGroupHandle * add_callback_group(
const rclcpp::CallbackGroup::SharedPtr & callback_group)
193 auto uPtr = get_handle_for_callback_group(callback_group);
194 CallbackGroupHandle * ret = uPtr.get();
196 std::lock_guard lk(ready_callback_groups_mutex);
198 callback_groups.push_back(std::move(uPtr));
202 void remove_callback_group(
const CallbackGroupHandle *callback_handle)
204 std::lock_guard lk(ready_callback_groups_mutex);
205 ready_callback_groups.erase(std::find(ready_callback_groups.begin(),
206 ready_callback_groups.end(), callback_handle));
208 callback_groups.remove_if([&callback_handle] (
const auto & e) {
209 return e.get() == callback_handle;
222 std::lock_guard l(ready_callback_groups_mutex);
223 ready_callback_groups.push_back(handle);
226 if(callback_group_was_idle) {
233 std::optional<ExecutableEntity> entity;
234 bool moreEntitiesReady{};
246 std::lock_guard l(ready_callback_groups_mutex);
255 return get_next_ready_entity_intern();
259 GlobalEventIdProvider::MonotonicId max_id)
262 std::lock_guard l(ready_callback_groups_mutex);
265 return ExecutableEntityWithInfo{
266 ExecutableEntity{sync_function,
nullptr},
271 return get_next_ready_entity_intern(max_id);
274 virtual ExecutableEntityWithInfo get_next_ready_entity_intern() = 0;
275 virtual ExecutableEntityWithInfo get_next_ready_entity_intern(
276 GlobalEventIdProvider::MonotonicId max_id) = 0;
288 bool wake_worker =
false;
290 std::lock_guard l(ready_callback_groups_mutex);
308 if(e.callback_handle !=
nullptr) {
319 std::lock_guard lk(ready_callback_groups_mutex);
320 release_worker_once =
true;
322 work_ready_conditional.notify_one();
325 void block_worker_thread()
327 std::unique_lock lk(ready_callback_groups_mutex);
328 work_ready_conditional.wait(lk, [
this]() ->
bool {
329 return !ready_callback_groups.empty() || release_worker_once || release_workers;
331 release_worker_once =
false;
334 void block_worker_thread_for(std::chrono::nanoseconds timeout)
336 std::unique_lock lk(ready_callback_groups_mutex);
337 work_ready_conditional.wait_for(lk, timeout, [
this]() ->
bool {
338 return !ready_callback_groups.empty() || release_worker_once || release_workers;
340 release_worker_once =
false;
343 void release_all_worker_threads()
346 std::lock_guard lk(ready_callback_groups_mutex);
347 release_workers =
true;
349 work_ready_conditional.notify_all();
353 virtual std::unique_ptr<CallbackGroupHandle> get_handle_for_callback_group(
354 const rclcpp::CallbackGroup::SharedPtr & callback_group) = 0;
358 std::function<void ()> sync_function;
360 bool needs_sync =
false;
362 std::mutex ready_callback_groups_mutex;
363 std::deque<CallbackGroupHandle *> ready_callback_groups;
365 bool release_workers =
false;
366 bool release_worker_once =
false;
368 std::condition_variable work_ready_conditional;
370 std::list<std::unique_ptr<CallbackGroupHandle>> callback_groups;
void unblock_one_worker_thread()
void callback_group_ready(CallbackGroupHandle *handle, bool callback_group_was_idle)
void mark_entity_as_executed(const ExecutableEntity &e)
ExecutableEntityWithInfo get_next_ready_entity()
CBGScheduler(std::function< void()> sync_function)
Versions of rosidl_typesupport_cpp::get_message_type_support_handle that handle adapted types.
virtual bool has_ready_entities() const =0
void add_ready_entity(const add_fun &fun)