Skip to content

add support for reentrant callback group to EventsCBGExecutor#3178

Open
armaho wants to merge 3 commits into
ros2:rollingfrom
armaho:events_cbg_executor_reentrant
Open

add support for reentrant callback group to EventsCBGExecutor#3178
armaho wants to merge 3 commits into
ros2:rollingfrom
armaho:events_cbg_executor_reentrant

Conversation

@armaho

@armaho armaho commented Jun 18, 2026

Copy link
Copy Markdown

Description

Fixes #3175

Is this user-facing behavior change?

Did you use Generative AI?

No

Additional Information

Signed-off-by: Arman Hosseini <armahosseini878787@gmail.com>
@skyegalaxy skyegalaxy requested review from jmachowinski and skyegalaxy and removed request for jmachowinski June 18, 2026 16:00

@skyegalaxy skyegalaxy left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm with green CI. will let @jmachowinski take a pass as well

{
ready_callback_groups.erase(it);
}
return CBGScheduler::ExecutableEntityWithInfo{

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note to self to remove C++20 initialization when backporting this to Jazzy and Kilted specifically

@skyegalaxy

Copy link
Copy Markdown
Member

actually @armaho can you add a test which exercises the reentrant path like we discussed at the client library WG meeting?

@armaho

armaho commented Jun 19, 2026

Copy link
Copy Markdown
Author

@skyegalaxy

Sure let me see how to test it.

@mergify

mergify Bot commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Tick the box to add this pull request to the merge queue (same as @mergifyio queue).

  • Queue this pull request

…er EventCBGExecutor

Signed-off-by: Arman Hosseini <armahosseini878787@gmail.com>
@armaho armaho force-pushed the events_cbg_executor_reentrant branch from 554512d to 855d1b2 Compare June 19, 2026 13:29
@armaho

armaho commented Jun 19, 2026

Copy link
Copy Markdown
Author

@skyegalaxy

I just added a test covering the reentrant callback group behavior. Could you take another look when you have time?

@jmachowinski jmachowinski left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the late reply.
I wonder if it makes sense to introduce a second class of callback handle, providing a seperate logic.
In this case the ready queue would be something like
std::deque<std::variant<ReentrantCallbackGroupHandle *, MutalExclusiveCallbackGroupHandle *>

Even though this would lead to some code duplication, I think it would make the code easier and better understandable in the end. The current approach of selectively doing things made it hard to understand what is going on.

I also think the compiler might optimize the variant better.

Comment thread rclcpp/src/rclcpp/executors/events_cbg_executor/first_in_first_out_scheduler.cpp Outdated
Comment thread rclcpp/src/rclcpp/executors/events_cbg_executor/scheduler.hpp Outdated
Comment on lines +234 to +252

// Reentrant callback groups might not be removed from the queue when one of
// their entities starts executing.
if (handle->get_type() == CallbackGroupType::Reentrant) {
bool already_in_queue = false;

for (auto it = ready_callback_groups.begin(); it != ready_callback_groups.end(); it++) {
if (*it == handle) {
already_in_queue = true;
break;
}
}

if (!already_in_queue) {
ready_callback_groups.push_back(handle);
}
} else {
ready_callback_groups.push_back(handle);
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a big no go, you introduce O(n) characteristics by searching the ready list.
This code should actually not be needed as the callback group handle should hold the information
if it is in the queue or not.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't able to find anything in the handle itself that indicates whether it's in the queue or not. There was an idle field, but I had trouble using it to determine that. I ended up adding an in_queue field to the handle instead, which is simple to understand and implement. What do you think about that?

@skyegalaxy

Copy link
Copy Markdown
Member

@armaho - do you have bandwidth to respond to the feedback / still want to work on this?

@armaho

armaho commented Jul 2, 2026

Copy link
Copy Markdown
Author

@skyegalaxy Yes. Sorry I’ve been busy I will address the problems of current code and check out that variant idea tomorrow and get back to you with the results.

Signed-off-by: Arman Hosseini <armahosseini878787@gmail.com>
@armaho armaho force-pushed the events_cbg_executor_reentrant branch from cfebaef to 490c6b0 Compare July 3, 2026 13:20
@armaho armaho requested a review from jmachowinski July 3, 2026 13:29
@armaho

armaho commented Jul 3, 2026

Copy link
Copy Markdown
Author

@jmachowinski

I also think that the current implementation of EventCBGExecutor is hard to understand. At least, it was for me.

But I don't think that creating a separate handle for reentrant cbgs would help that much. Right now, the only conditional piece of code within the CallbackGroupHandle itself is inside mark_as_executing:

void mark_as_executing()
{
  if (type != CallbackGroupType::Reentrant) {
    not_ready = true;
  }
}

Which is not hard to understand, and I don't think that creating a separate handle would fundamentally reduce the conditional logic elsewhere in the code. To me, it doesn’t seem worth the amount of code duplication it would introduce.

That said, you know this codebase much better than I do, so I'll go in whichever direction you think is best.

@jmachowinski

Copy link
Copy Markdown
Collaborator

The commit looks good so far. I started playing around with the API to see if splitting the handle base class makes it more readable. I'll report back next week. Have a nice weekend.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

EventsCBGExecutor treats reentrant callback groups like they're mutually exclusive

3 participants