Merge pull request #80 from ros2/fix_erase_while_iterating
fix erase while iterating
This commit is contained in:
commit
3f2df48fef
1 changed files with 28 additions and 44 deletions
|
@ -549,30 +549,6 @@ protected:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
remove_subscriber_handle_from_subscriber_handles(void * handle)
|
|
||||||
{
|
|
||||||
subscriber_handles_.remove(handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
remove_guard_condition_handle_from_guard_condition_handles(void * handle)
|
|
||||||
{
|
|
||||||
guard_condition_handles_.remove(handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
remove_service_handle_from_service_handles(void * handle)
|
|
||||||
{
|
|
||||||
service_handles_.remove(handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
remove_client_handle_from_client_handles(void * handle)
|
|
||||||
{
|
|
||||||
client_handles_.remove(handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
rclcpp::node::Node::SharedPtr
|
rclcpp::node::Node::SharedPtr
|
||||||
get_node_by_group(rclcpp::callback_group::CallbackGroup::SharedPtr & group)
|
get_node_by_group(rclcpp::callback_group::CallbackGroup::SharedPtr & group)
|
||||||
{
|
{
|
||||||
|
@ -622,31 +598,33 @@ protected:
|
||||||
void
|
void
|
||||||
get_next_timer(AnyExecutable::SharedPtr & any_exec)
|
get_next_timer(AnyExecutable::SharedPtr & any_exec)
|
||||||
{
|
{
|
||||||
for (auto handle : guard_condition_handles_) {
|
auto it = guard_condition_handles_.begin();
|
||||||
auto timer = get_timer_by_handle(handle);
|
while (it != guard_condition_handles_.end()) {
|
||||||
|
auto timer = get_timer_by_handle(*it);
|
||||||
if (timer) {
|
if (timer) {
|
||||||
// Find the group for this handle and see if it can be serviced
|
// Find the group for this handle and see if it can be serviced
|
||||||
auto group = get_group_by_timer(timer);
|
auto group = get_group_by_timer(timer);
|
||||||
if (!group) {
|
if (!group) {
|
||||||
// Group was not found, meaning the timer is not valid...
|
// Group was not found, meaning the timer is not valid...
|
||||||
// Remove it from the ready list and continue looking
|
// Remove it from the ready list and continue looking
|
||||||
remove_guard_condition_handle_from_guard_condition_handles(handle);
|
guard_condition_handles_.erase(it++);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!group->can_be_taken_from_.load()) {
|
if (!group->can_be_taken_from_.load()) {
|
||||||
// Group is mutually exclusive and is being used, so skip it for now
|
// Group is mutually exclusive and is being used, so skip it for now
|
||||||
// Leave it to be checked next time, but continue searching
|
// Leave it to be checked next time, but continue searching
|
||||||
|
++it;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Otherwise it is safe to set and return the any_exec
|
// Otherwise it is safe to set and return the any_exec
|
||||||
any_exec->timer = timer;
|
any_exec->timer = timer;
|
||||||
any_exec->callback_group = group;
|
any_exec->callback_group = group;
|
||||||
any_exec->node = get_node_by_group(group);
|
any_exec->node = get_node_by_group(group);
|
||||||
remove_guard_condition_handle_from_guard_condition_handles(handle);
|
guard_condition_handles_.erase(it++);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Else, the timer is no longer valid, remove it and continue
|
// Else, the timer is no longer valid, remove it and continue
|
||||||
remove_guard_condition_handle_from_guard_condition_handles(handle);
|
guard_condition_handles_.erase(it++);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -675,31 +653,33 @@ protected:
|
||||||
void
|
void
|
||||||
get_next_subscription(AnyExecutable::SharedPtr & any_exec)
|
get_next_subscription(AnyExecutable::SharedPtr & any_exec)
|
||||||
{
|
{
|
||||||
for (auto handle : subscriber_handles_) {
|
auto it = subscriber_handles_.begin();
|
||||||
auto subscription = get_subscription_by_handle(handle);
|
while (it != subscriber_handles_.end()) {
|
||||||
|
auto subscription = get_subscription_by_handle(*it);
|
||||||
if (subscription) {
|
if (subscription) {
|
||||||
// Find the group for this handle and see if it can be serviced
|
// Find the group for this handle and see if it can be serviced
|
||||||
auto group = get_group_by_subscription(subscription);
|
auto group = get_group_by_subscription(subscription);
|
||||||
if (!group) {
|
if (!group) {
|
||||||
// Group was not found, meaning the subscription is not valid...
|
// Group was not found, meaning the subscription is not valid...
|
||||||
// Remove it from the ready list and continue looking
|
// Remove it from the ready list and continue looking
|
||||||
remove_subscriber_handle_from_subscriber_handles(handle);
|
subscriber_handles_.erase(it++);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!group->can_be_taken_from_.load()) {
|
if (!group->can_be_taken_from_.load()) {
|
||||||
// Group is mutually exclusive and is being used, so skip it for now
|
// Group is mutually exclusive and is being used, so skip it for now
|
||||||
// Leave it to be checked next time, but continue searching
|
// Leave it to be checked next time, but continue searching
|
||||||
|
++it;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Otherwise it is safe to set and return the any_exec
|
// Otherwise it is safe to set and return the any_exec
|
||||||
any_exec->subscription = subscription;
|
any_exec->subscription = subscription;
|
||||||
any_exec->callback_group = group;
|
any_exec->callback_group = group;
|
||||||
any_exec->node = get_node_by_group(group);
|
any_exec->node = get_node_by_group(group);
|
||||||
remove_subscriber_handle_from_subscriber_handles(handle);
|
subscriber_handles_.erase(it++);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Else, the subscription is no longer valid, remove it and continue
|
// Else, the subscription is no longer valid, remove it and continue
|
||||||
remove_subscriber_handle_from_subscriber_handles(handle);
|
subscriber_handles_.erase(it++);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -727,31 +707,33 @@ protected:
|
||||||
void
|
void
|
||||||
get_next_service(AnyExecutable::SharedPtr & any_exec)
|
get_next_service(AnyExecutable::SharedPtr & any_exec)
|
||||||
{
|
{
|
||||||
for (auto handle : service_handles_) {
|
auto it = service_handles_.begin();
|
||||||
auto service = get_service_by_handle(handle);
|
while (it != service_handles_.end()) {
|
||||||
|
auto service = get_service_by_handle(*it);
|
||||||
if (service) {
|
if (service) {
|
||||||
// Find the group for this handle and see if it can be serviced
|
// Find the group for this handle and see if it can be serviced
|
||||||
auto group = get_group_by_service(service);
|
auto group = get_group_by_service(service);
|
||||||
if (!group) {
|
if (!group) {
|
||||||
// Group was not found, meaning the service is not valid...
|
// Group was not found, meaning the service is not valid...
|
||||||
// Remove it from the ready list and continue looking
|
// Remove it from the ready list and continue looking
|
||||||
remove_service_handle_from_service_handles(handle);
|
service_handles_.erase(it++);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!group->can_be_taken_from_.load()) {
|
if (!group->can_be_taken_from_.load()) {
|
||||||
// Group is mutually exclusive and is being used, so skip it for now
|
// Group is mutually exclusive and is being used, so skip it for now
|
||||||
// Leave it to be checked next time, but continue searching
|
// Leave it to be checked next time, but continue searching
|
||||||
|
++it;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Otherwise it is safe to set and return the any_exec
|
// Otherwise it is safe to set and return the any_exec
|
||||||
any_exec->service = service;
|
any_exec->service = service;
|
||||||
any_exec->callback_group = group;
|
any_exec->callback_group = group;
|
||||||
any_exec->node = get_node_by_group(group);
|
any_exec->node = get_node_by_group(group);
|
||||||
remove_service_handle_from_service_handles(handle);
|
service_handles_.erase(it++);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Else, the service is no longer valid, remove it and continue
|
// Else, the service is no longer valid, remove it and continue
|
||||||
remove_service_handle_from_service_handles(handle);
|
service_handles_.erase(it++);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -779,31 +761,33 @@ protected:
|
||||||
void
|
void
|
||||||
get_next_client(AnyExecutable::SharedPtr & any_exec)
|
get_next_client(AnyExecutable::SharedPtr & any_exec)
|
||||||
{
|
{
|
||||||
for (auto handle : client_handles_) {
|
auto it = client_handles_.begin();
|
||||||
auto client = get_client_by_handle(handle);
|
while (it != client_handles_.end()) {
|
||||||
|
auto client = get_client_by_handle(*it);
|
||||||
if (client) {
|
if (client) {
|
||||||
// Find the group for this handle and see if it can be serviced
|
// Find the group for this handle and see if it can be serviced
|
||||||
auto group = get_group_by_client(client);
|
auto group = get_group_by_client(client);
|
||||||
if (!group) {
|
if (!group) {
|
||||||
// Group was not found, meaning the service is not valid...
|
// Group was not found, meaning the service is not valid...
|
||||||
// Remove it from the ready list and continue looking
|
// Remove it from the ready list and continue looking
|
||||||
remove_client_handle_from_client_handles(handle);
|
client_handles_.erase(it++);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!group->can_be_taken_from_.load()) {
|
if (!group->can_be_taken_from_.load()) {
|
||||||
// Group is mutually exclusive and is being used, so skip it for now
|
// Group is mutually exclusive and is being used, so skip it for now
|
||||||
// Leave it to be checked next time, but continue searching
|
// Leave it to be checked next time, but continue searching
|
||||||
|
++it;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Otherwise it is safe to set and return the any_exec
|
// Otherwise it is safe to set and return the any_exec
|
||||||
any_exec->client = client;
|
any_exec->client = client;
|
||||||
any_exec->callback_group = group;
|
any_exec->callback_group = group;
|
||||||
any_exec->node = get_node_by_group(group);
|
any_exec->node = get_node_by_group(group);
|
||||||
remove_client_handle_from_client_handles(handle);
|
client_handles_.erase(it++);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Else, the service is no longer valid, remove it and continue
|
// Else, the service is no longer valid, remove it and continue
|
||||||
remove_client_handle_from_client_handles(handle);
|
client_handles_.erase(it++);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue