fix race conditions in guard condition handling (#325)
This commit is contained in:
parent
675ad04c76
commit
100417a98d
2 changed files with 14 additions and 11 deletions
|
@ -70,6 +70,12 @@ bool
|
||||||
ClientBase::wait_for_service_nanoseconds(std::chrono::nanoseconds timeout)
|
ClientBase::wait_for_service_nanoseconds(std::chrono::nanoseconds timeout)
|
||||||
{
|
{
|
||||||
auto start = std::chrono::steady_clock::now();
|
auto start = std::chrono::steady_clock::now();
|
||||||
|
// make an event to reuse, rather than create a new one each time
|
||||||
|
auto node_ptr = node_graph_.lock();
|
||||||
|
if (!node_ptr) {
|
||||||
|
throw InvalidNodeError();
|
||||||
|
}
|
||||||
|
auto event = node_ptr->get_graph_event();
|
||||||
// check to see if the server is ready immediately
|
// check to see if the server is ready immediately
|
||||||
if (this->service_is_ready()) {
|
if (this->service_is_ready()) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -78,12 +84,6 @@ ClientBase::wait_for_service_nanoseconds(std::chrono::nanoseconds timeout)
|
||||||
// check was non-blocking, return immediately
|
// check was non-blocking, return immediately
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// make an event to reuse, rather than create a new one each time
|
|
||||||
auto node_ptr = node_graph_.lock();
|
|
||||||
if (!node_ptr) {
|
|
||||||
throw InvalidNodeError();
|
|
||||||
}
|
|
||||||
auto event = node_ptr->get_graph_event();
|
|
||||||
// update the time even on the first loop to account for time spent in the first call
|
// update the time even on the first loop to account for time spent in the first call
|
||||||
// to this->server_is_ready()
|
// to this->server_is_ready()
|
||||||
std::chrono::nanoseconds time_to_wait = timeout - (std::chrono::steady_clock::now() - start);
|
std::chrono::nanoseconds time_to_wait = timeout - (std::chrono::steady_clock::now() - start);
|
||||||
|
|
|
@ -205,13 +205,13 @@ NodeGraph::get_graph_event()
|
||||||
{
|
{
|
||||||
auto event = rclcpp::event::Event::make_shared();
|
auto event = rclcpp::event::Event::make_shared();
|
||||||
std::lock_guard<std::mutex> graph_changed_lock(graph_mutex_);
|
std::lock_guard<std::mutex> graph_changed_lock(graph_mutex_);
|
||||||
|
graph_events_.push_back(event);
|
||||||
|
graph_users_count_++;
|
||||||
// on first call, add node to graph_listener_
|
// on first call, add node to graph_listener_
|
||||||
if (should_add_to_graph_listener_.exchange(false)) {
|
if (should_add_to_graph_listener_.exchange(false)) {
|
||||||
graph_listener_->add_node(this);
|
graph_listener_->add_node(this);
|
||||||
graph_listener_->start_if_not_started();
|
graph_listener_->start_if_not_started();
|
||||||
}
|
}
|
||||||
graph_events_.push_back(event);
|
|
||||||
graph_users_count_++;
|
|
||||||
return event;
|
return event;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -238,10 +238,13 @@ NodeGraph::wait_for_graph_change(
|
||||||
throw EventNotRegisteredError();
|
throw EventNotRegisteredError();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
auto pred = [&event]() {
|
||||||
|
return event->check() || !rclcpp::utilities::ok();
|
||||||
|
};
|
||||||
std::unique_lock<std::mutex> graph_lock(graph_mutex_);
|
std::unique_lock<std::mutex> graph_lock(graph_mutex_);
|
||||||
graph_cv_.wait_for(graph_lock, timeout, [&event]() {
|
if (!pred()) {
|
||||||
return event->check() || !rclcpp::utilities::ok();
|
graph_cv_.wait_for(graph_lock, timeout, pred);
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue