Skip to content

Conversation

kkysen
Copy link
Collaborator

@kkysen kkysen commented Jul 18, 2024

We may be able to replace SendSyncNonNull with Unique, but we can do that later. They have basically the same APIs, though slightly different safety invariants (uniqueness vs. thread-safe).

@kkysen kkysen requested a review from rinon July 18, 2024 02:51
pub fn wrap_buf<BD: BitDepth>(buf: &mut [BD::Pixel], stride: usize) -> Self {
let buf = AsBytes::as_bytes_mut(buf);
let ptr = NonNull::new(buf.as_mut_ptr()).unwrap();
let ptr = Unique::from_ref_mut(buf).cast();
Copy link
Collaborator

Choose a reason for hiding this comment

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

How is this unique in the wrap_buf case? We're borrowing a reference to this data, right? So should we really use unique here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

A &mut reference is always unique. So it can be &mut or owned. core::ptr::Unique impls From<&mut T> even.

Copy link
Collaborator

Choose a reason for hiding this comment

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

But once that constructor returns the borrow is over, unless there's a lifetime. So it's no longer unique? How do we ensure no where else has a pointer to the same thing?

NonNull::new(self.as_strided_byte_mut_ptr().cast())
let ptr = NonNull::new(self.as_strided_byte_mut_ptr()).unwrap();
// SAFETY: The `ptr` originally comes from a `Unique` in `Rav1dPictureDataComponentInner::ptr`.
let ptr = unsafe { Unique::new(ptr) };
Copy link
Collaborator

Choose a reason for hiding this comment

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

Again, how is this unique? Can this method return a NonNull instead?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Because self.as_strided_byte_mut_ptr() is derived from Rav1dPictureDataComponentInner::ptr, which is a Unique. I can say that more explicitly if that's clearer.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Does that mean there's two Uniques pointing to the same data? The original and the one into the middle?

Copy link
Collaborator

Choose a reason for hiding this comment

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

e.g. can I just call this twice and get two Uniques? Doesn't that violate the invariants?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Ugh, yeah, you're right.

Why does core::ptr::Unique: Copy + Clone then?

Copy link
Collaborator

Choose a reason for hiding this comment

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

No idea.

@kkysen kkysen requested a review from rinon July 18, 2024 08:07
@rinon
Copy link
Collaborator

rinon commented Jul 18, 2024

To follow up on the discussion of "should DisjointMut require T: Sync," DisjointMut is effectively a ranged RwLock, which does require T: Sync to allow concurrent reads from multiple threads (which is what Sync means). I think we should impl Sync for this data pointer but I don't think it can be Unique. Could we just have a new PictureDataPtr type that wraps NonNull and documents the lifetime invariants?

@kkysen kkysen force-pushed the kkysen/Rav1dPictureDataComponentInner-ptr-Unique branch from 64390bb to 5366e5a Compare May 23, 2025 19:00
Co-authored-by: Stephen Crane <sjc@immunant.com>
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