Skip to content

Commit

Permalink
Fix callback accessing invalid reference to promise (#268)
Browse files Browse the repository at this point in the history
### Public-Facing Changes

Fix callback accessing invalid reference to promise

### Description
For ROS1, the service request and response types can only be retrieved
by opening a connection to the service server. For this, we use
`ros::ServiceManager::instance()->createServiceServerLink` which under
the hood keeps a copy of the returned pointer, effectively keeping the
connection alive. This patch makes sure that we drop the connection when
we either have received the header or when the timeout has been
exceeded. This avoids that the header-received callback is being called
with an invalid reference to the promise.

Fixes #267 
Resolves FG-5366
  • Loading branch information
achim-k authored Oct 23, 2023
1 parent a2f88a9 commit e52bb9d
Showing 1 changed file with 6 additions and 1 deletion.
7 changes: 6 additions & 1 deletion ros1_foxglove_bridge/src/service_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,23 @@ std::string retrieveServiceType(const std::string& serviceName, std::chrono::mil
auto future = promise.get_future();

link->getConnection()->setHeaderReceivedCallback(
[&promise](const ros::ConnectionPtr&, const ros::Header& header) {
[&promise](const ros::ConnectionPtr& conn, const ros::Header& header) {
std::string serviceType;
if (header.getValue("type", serviceType)) {
promise.set_value(serviceType);
} else {
promise.set_exception(std::make_exception_ptr(
std::runtime_error("Key 'type' not found in service connection header")));
}
// Close connection since we don't need it any more.
conn->drop(ros::Connection::DropReason::Destructing);
return true;
});

if (future.wait_for(timeout) != std::future_status::ready) {
// Drop connection here, removes the link from the service manager instance and avoids
// that the header-received callback is called after the promise has already been destroyed.
link->getConnection()->drop(ros::Connection::DropReason::Destructing);
throw std::runtime_error("Timed out when retrieving service type");
}

Expand Down

0 comments on commit e52bb9d

Please sign in to comment.