-
Notifications
You must be signed in to change notification settings - Fork 34
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Thread-safe access to SubscriptionData #288
base: rolling
Are you sure you want to change the base?
Conversation
Signed-off-by: Yadunund <[email protected]>
…imitation Signed-off-by: Yadunund <[email protected]>
619b33f
to
71bbb6a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This generally looks good. I've left some things to improved, and it needs to be rebased. Once those are done, I'll run some more extensive tests on it.
@@ -237,8 +237,12 @@ std::string zid_to_str(const z_id_t & id); | |||
} // namespace liveliness | |||
|
|||
///============================================================================= | |||
// Helper function to generate a randon GID. | |||
/// Helper function to generate a randon GID. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// Helper function to generate a randon GID. | |
/// Helper function to generate a random GID. |
|
||
///============================================================================= | ||
/// Generate a hash for a given GID. | ||
size_t hash_gid(const uint8_t * gid); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know you are just copying this over, but I'm going to suggest that we change this signature to:
size_t hash_gid(const uint8_t * gid); | |
size_t hash_gid(const uint8_t gid[RMW_GID_STORAGE_SIZE]); |
It won't make much of a practical difference, but it will be clear to the reader exactly what the size of gid is.
@@ -69,12 +69,14 @@ rmw_publisher_event_init( | |||
rmw_event->event_type = event_type; | |||
|
|||
// Register the event with graph cache. | |||
std::weak_ptr<rmw_zenoh_cpp::PublisherData> data_wp = pub_data; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this a separate bugfix?
zenoh_event_type, | ||
[sub_data, | ||
zenoh_event_type](std::unique_ptr<rmw_zenoh_cpp::rmw_zenoh_event_status_t> zenoh_event) | ||
{ | ||
// auto sub_data = data_wp.lock(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// auto sub_data = data_wp.lock(); |
// Store type erased node in rmw_subscription->data so that the | ||
// Subscription can be safely accessed. | ||
// TODO(Yadunund): We cannot store the rmw_node_t * here since this type erased | ||
// subscription handle will be returned in the rmw_subscriptions_t in rmw_wait | ||
// from which we cannot obtain SubscriptionData. | ||
// rmw_subscription->data = reinterpret_cast<void *>(const_cast<rmw_node_t *>(node)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// Store type erased node in rmw_subscription->data so that the | |
// Subscription can be safely accessed. | |
// TODO(Yadunund): We cannot store the rmw_node_t * here since this type erased | |
// subscription handle will be returned in the rmw_subscriptions_t in rmw_wait | |
// from which we cannot obtain SubscriptionData. | |
// rmw_subscription->data = reinterpret_cast<void *>(const_cast<rmw_node_t *>(node)); | |
// TODO(Yadunund): We cannot store the rmw_node_t * here since this type erased | |
// subscription handle will be returned in the rmw_subscriptions_t in rmw_wait | |
// from which we cannot obtain SubscriptionData. |
rmw_zenoh_cpp::SubscriptionData * sub_data = | ||
static_cast<rmw_zenoh_cpp::SubscriptionData *>(subscriptions->subscribers[i]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we still want to check whether sub_data
is NULL before doing anything:
rmw_zenoh_cpp::SubscriptionData * sub_data = | |
static_cast<rmw_zenoh_cpp::SubscriptionData *>(subscriptions->subscribers[i]); | |
rmw_zenoh_cpp::SubscriptionData * sub_data = | |
static_cast<rmw_zenoh_cpp::SubscriptionData *>(subscriptions->subscribers[i]); | |
if (sub_data == nullptr) { | |
continue; | |
} |
This PR introduces SubscriptionData class that manages the lifetime of Zenoh artifacts. It makes access to class members thread-safe where possible. Some z_closure callbacks still work with type erased raw ptrs but this will be addressed when we migrate to zenoh-cpp.
It seems like it is not feasible to store rmw_node_t * as type erased void * in rmw_subscription_t->data like we did with rmw_publisher_t->data .
The problem is that because rmw_subscriptions_t in rmw_wait contains an array of the type erased subscriptions handles (ie, rmw_subscription_t->data ), there is no way to get the SubscriptionData::SharedPtr here
rmw_zenoh/rmw_zenoh_cpp/src/rmw_zenoh.cpp
Lines 3220 to 3221 in cf8e8a2
The only option we have is storing a rawptr to SubscriptionData in rmw_subscription_t->data but leads to the risk of it becoming a dangling pointer when the SubscriptionData::SharedPtr is deleted.