Messages in this thread | | | Date | Wed, 31 May 2023 14:07:49 +0000 | Subject | Re: [PATCH v1 6/7] rust: workqueue: add safe API to workqueue | From | Alice Ryhl <> |
| |
Andreas Hindborg <nmi@metaspace.dk> writes: > Alice Ryhl <aliceryhl@google.com> writes: >> +unsafe impl<T> WorkItem for Arc<T> >> +where >> + T: ArcWorkItem + HasWork<Self> + ?Sized, >> +{ >> + type EnqueueOutput = Result<(), Self>; >> + >> + unsafe fn __enqueue<F>(self, queue_work_on: F) -> Self::EnqueueOutput >> + where >> + F: FnOnce(*mut bindings::work_struct) -> bool, >> + { >> + let ptr = Arc::into_raw(self); >> + >> + // Using `get_work_offset` here for object-safety. >> + // >> + // SAFETY: The pointer is valid since we just got it from `into_raw`. >> + let off = unsafe { (&*ptr).get_work_offset() }; >> + >> + // SAFETY: The `HasWork` impl promises that this offset gives us a field of type >> + // `Work<Self>` in the same allocation. >> + let work_ptr = unsafe { (ptr as *const u8).add(off) as *const Work<Self> }; > > We have this functionality in the default impl of > `HasWork<T>::raw_get_work() where Self: Sized`. I am uncertain about the > `Sized` bound. If it is sound to do the offset calculation here where > `T: ?Sized`, it should also be sound in the default implementation of > `HasWork<T>`. Should we not be able to change the bound on > `HasWork<T>::raw_get_work()` to `Self: ?Sized` and call into that from > here? > > let work_ptr = unsafe { <T as HasWork<Self>>::raw_get_work(ptr as _) }; > > Same for Box. > > BR Andreas
I looked into this, and it seems like we can remove `Self: Sized` bound from `raw_get_work`, so I am able to simplify this code somewhat. However, it cannot be removed from `container_of`.
Thanks, Alice
| |