Skip to content
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

Open
wants to merge 2 commits into
base: rolling
Choose a base branch
from
Open

Conversation

Yadunund
Copy link
Member

@Yadunund Yadunund commented Oct 2, 2024

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

auto sub_data =
static_cast<rmw_zenoh_cpp::rmw_subscription_data_t *>(subscriptions->subscribers[i]);
. ie we cannot traverse the heirarchy from rmw_subscription->data->rmw_node_t->context->impl->get_node_data()->get_sub_data().

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.

Copy link
Collaborator

@clalancette clalancette left a 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.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// 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);
Copy link
Collaborator

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:

Suggested change
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;
Copy link
Collaborator

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();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// auto sub_data = data_wp.lock();

Comment on lines +973 to +978
// 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));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// 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.

Comment on lines +2760 to +2761
rmw_zenoh_cpp::SubscriptionData * sub_data =
static_cast<rmw_zenoh_cpp::SubscriptionData *>(subscriptions->subscribers[i]);
Copy link
Collaborator

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:

Suggested change
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;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants