Skip to content

Commit 68b4d9a

Browse files
authored
Use weak pointers in rmw_context_impl_s. (#345)
Signed-off-by: Chris Lalancette <clalancette@gmail.com>
1 parent 86ccf3f commit 68b4d9a

File tree

1 file changed

+22
-37
lines changed

1 file changed

+22
-37
lines changed

rmw_zenoh_cpp/src/detail/rmw_context_impl_s.cpp

+22-37
Original file line numberDiff line numberDiff line change
@@ -43,17 +43,10 @@
4343
// TODO(clalancette): Make this configurable, or get it from the configuration
4444
#define SHM_BUFFER_SIZE_MB 10
4545

46-
// This global mapping of raw Data pointers to Data shared pointers allows graph_sub_data_handler()
47-
// to lookup the pointer, and gain a reference to a shared_ptr if it exists.
48-
// This guarantees that the Data object will not be destroyed while we are using it.
49-
static std::mutex data_to_data_shared_ptr_map_mutex;
50-
static std::unordered_map<rmw_context_impl_s::Data *,
51-
std::shared_ptr<rmw_context_impl_s::Data>> data_to_data_shared_ptr_map;
52-
5346
// Bundle all class members into a data struct which can be passed as a
5447
// weak ptr to various threads for thread-safe access without capturing
5548
// "this" ptr by reference.
56-
class rmw_context_impl_s::Data final
49+
class rmw_context_impl_s::Data final : public std::enable_shared_from_this<Data>
5750
{
5851
public:
5952
// Constructor.
@@ -64,7 +57,8 @@ class rmw_context_impl_s::Data final
6457
enclave_(std::move(enclave)),
6558
is_shutdown_(false),
6659
next_entity_id_(0),
67-
nodes_({})
60+
nodes_({}),
61+
liveliness_keyexpr_(rmw_zenoh_cpp::liveliness::subscription_token(domain_id))
6862
{
6963
// Initialize the zenoh configuration.
7064
std::optional<zenoh::Config> config = rmw_zenoh_cpp::get_z_config(
@@ -127,8 +121,6 @@ class rmw_context_impl_s::Data final
127121
graph_cache_ =
128122
std::make_shared<rmw_zenoh_cpp::GraphCache>(this->session_->get_zid());
129123
// Setup liveliness subscriptions for discovery.
130-
std::string liveliness_str = rmw_zenoh_cpp::liveliness::subscription_token(domain_id);
131-
132124
// Query router/liveliness participants to get graph information before the session was started.
133125
// We create a blocking channel that is unbounded, ie. `bound` = 0, to receive
134126
// replies for the z_liveliness_get() call. This is necessary as if the `bound`
@@ -147,14 +139,12 @@ class rmw_context_impl_s::Data final
147139

148140
// Intuitively use a FIFO channel rather than building it up with a closure and a
149141
// handler to FIFO channel
150-
zenoh::KeyExpr keyexpr(liveliness_str);
151-
152142
zenoh::Session::GetOptions options = zenoh::Session::GetOptions::create_default();
153143
options.target = zenoh::QueryTarget::Z_QUERY_TARGET_ALL;
154144
options.payload = "";
155145

156146
auto replies = session_->liveliness_get(
157-
keyexpr,
147+
liveliness_keyexpr_,
158148
zenoh::channels::FifoChannel(SIZE_MAX - 1),
159149
zenoh::Session::LivelinessGetOptions::create_default(),
160150
&result);
@@ -193,29 +183,29 @@ class rmw_context_impl_s::Data final
193183
graph_guard_condition_ = std::make_unique<rmw_guard_condition_t>();
194184
graph_guard_condition_->implementation_identifier = rmw_zenoh_cpp::rmw_zenoh_identifier;
195185
graph_guard_condition_->data = &guard_condition_data_;
186+
}
196187

188+
void init()
189+
{
197190
// Setup the liveliness subscriber to receives updates from the ROS graph
198191
// and update the graph cache.
199-
zenoh::KeyExpr keyexpr_cpp(liveliness_str.c_str());
200192
zenoh::Session::LivelinessSubscriberOptions sub_options =
201193
zenoh::Session::LivelinessSubscriberOptions::create_default();
202194
sub_options.history = true;
203-
graph_subscriber_ = session_->liveliness_declare_subscriber(
204-
keyexpr_cpp,
205-
[&](const zenoh::Sample & sample) {
206-
// Look up the data shared_ptr in the global map. If it is in there, use it.
207-
// If not, it is being shutdown so we can just ignore this update.
208-
std::shared_ptr<rmw_context_impl_s::Data> data_shared_ptr{nullptr};
209-
{
210-
std::lock_guard<std::mutex> lk(data_to_data_shared_ptr_map_mutex);
211-
if (data_to_data_shared_ptr_map.count(this) == 0) {
212-
return;
213-
}
214-
data_shared_ptr = data_to_data_shared_ptr_map[this];
215-
}
216195

196+
// This can't be in the constructor since shared_from_this() doesn't work there.
197+
std::weak_ptr<Data> context_impl_data_wp = shared_from_this();
198+
zenoh::ZResult result;
199+
graph_subscriber_ = session_->liveliness_declare_subscriber(
200+
liveliness_keyexpr_,
201+
[context_impl_data_wp](const zenoh::Sample & sample) {
217202
// Update the graph cache.
218-
data_shared_ptr->update_graph_cache(
203+
std::shared_ptr<Data> context_impl_data = context_impl_data_wp.lock();
204+
if (context_impl_data == nullptr) {
205+
RMW_ZENOH_LOG_ERROR_NAMED("rmw_zenoh_cpp", "Unable to obtain context_impl.");
206+
return;
207+
}
208+
context_impl_data->update_graph_cache(
219209
sample,
220210
std::string(sample.get_keyexpr().as_string_view()));
221211
},
@@ -435,6 +425,8 @@ class rmw_context_impl_s::Data final
435425
std::size_t next_entity_id_;
436426
// Nodes created from this context.
437427
std::unordered_map<const rmw_node_t *, std::shared_ptr<rmw_zenoh_cpp::NodeData>> nodes_;
428+
429+
zenoh::KeyExpr liveliness_keyexpr_;
438430
};
439431

440432
///=============================================================================
@@ -443,9 +435,7 @@ rmw_context_impl_s::rmw_context_impl_s(
443435
const std::string & enclave)
444436
{
445437
data_ = std::make_shared<Data>(domain_id, std::move(enclave));
446-
447-
std::lock_guard<std::mutex> lk(data_to_data_shared_ptr_map_mutex);
448-
data_to_data_shared_ptr_map.emplace(data_.get(), data_);
438+
data_->init();
449439
}
450440

451441
///=============================================================================
@@ -487,11 +477,6 @@ std::size_t rmw_context_impl_s::get_next_entity_id()
487477
///=============================================================================
488478
rmw_ret_t rmw_context_impl_s::shutdown()
489479
{
490-
{
491-
std::lock_guard<std::mutex> lk(data_to_data_shared_ptr_map_mutex);
492-
data_to_data_shared_ptr_map.erase(data_.get());
493-
}
494-
495480
return data_->shutdown();
496481
}
497482

0 commit comments

Comments
 (0)