From 8d3e5fa0ae31a4b00ef7dc8d895e12865af08747 Mon Sep 17 00:00:00 2001 From: Kevin Mehall Date: Mon, 2 Sep 2024 17:38:51 -0600 Subject: [PATCH 1/3] Move the `data` and `vtable` methods from `RawWaker` to `Waker` Per the `waker_getters` FCP: https://github.com/rust-lang/rust/issues/96992#issuecomment-1941998046 --- library/core/src/task/wake.rs | 44 +++++++++++++++++------------------ library/core/tests/waker.rs | 11 ++++----- 2 files changed, 27 insertions(+), 28 deletions(-) diff --git a/library/core/src/task/wake.rs b/library/core/src/task/wake.rs index 7e5c1574f5367..9baaa274bb071 100644 --- a/library/core/src/task/wake.rs +++ b/library/core/src/task/wake.rs @@ -60,22 +60,6 @@ impl RawWaker { RawWaker { data, vtable } } - /// Gets the `data` pointer used to create this `RawWaker`. - #[inline] - #[must_use] - #[unstable(feature = "waker_getters", issue = "96992")] - pub fn data(&self) -> *const () { - self.data - } - - /// Gets the `vtable` pointer used to create this `RawWaker`. - #[inline] - #[must_use] - #[unstable(feature = "waker_getters", issue = "96992")] - pub fn vtable(&self) -> &'static RawWakerVTable { - self.vtable - } - #[unstable(feature = "noop_waker", issue = "98286")] const NOOP: RawWaker = { const VTABLE: RawWakerVTable = RawWakerVTable::new( @@ -565,12 +549,20 @@ impl Waker { WAKER } - /// Gets a reference to the underlying [`RawWaker`]. + /// Gets the `data` pointer used to create this `Waker`. #[inline] #[must_use] #[unstable(feature = "waker_getters", issue = "96992")] - pub fn as_raw(&self) -> &RawWaker { - &self.waker + pub fn data(&self) -> *const () { + self.waker.data + } + + /// Gets the `vtable` pointer used to create this `Waker`. + #[inline] + #[must_use] + #[unstable(feature = "waker_getters", issue = "96992")] + pub fn vtable(&self) -> &'static RawWakerVTable { + self.waker.vtable } } @@ -831,12 +823,20 @@ impl LocalWaker { WAKER } - /// Gets a reference to the underlying [`RawWaker`]. + /// Gets the `data` pointer used to create this `LocalWaker`. #[inline] #[must_use] #[unstable(feature = "waker_getters", issue = "96992")] - pub fn as_raw(&self) -> &RawWaker { - &self.waker + pub fn data(&self) -> *const () { + self.waker.data + } + + /// Gets the `vtable` pointer used to create this `LocalWaker`. + #[inline] + #[must_use] + #[unstable(feature = "waker_getters", issue = "96992")] + pub fn vtable(&self) -> &'static RawWakerVTable { + self.waker.vtable } } #[unstable(feature = "local_waker", issue = "118959")] diff --git a/library/core/tests/waker.rs b/library/core/tests/waker.rs index 361e900e69562..8f6bf0565fc35 100644 --- a/library/core/tests/waker.rs +++ b/library/core/tests/waker.rs @@ -4,14 +4,13 @@ use std::task::{RawWaker, RawWakerVTable, Waker}; #[test] fn test_waker_getters() { let raw_waker = RawWaker::new(ptr::without_provenance_mut(42usize), &WAKER_VTABLE); - assert_eq!(raw_waker.data() as usize, 42); - assert!(ptr::eq(raw_waker.vtable(), &WAKER_VTABLE)); - let waker = unsafe { Waker::from_raw(raw_waker) }; + assert_eq!(waker.data() as usize, 42); + assert!(ptr::eq(waker.vtable(), &WAKER_VTABLE)); + let waker2 = waker.clone(); - let raw_waker2 = waker2.as_raw(); - assert_eq!(raw_waker2.data() as usize, 43); - assert!(ptr::eq(raw_waker2.vtable(), &WAKER_VTABLE)); + assert_eq!(waker2.data() as usize, 43); + assert!(ptr::eq(waker2.vtable(), &WAKER_VTABLE)); } static WAKER_VTABLE: RawWakerVTable = RawWakerVTable::new( From 2dc75148ee4ac7e6edfc25911b28b877e1bed0f6 Mon Sep 17 00:00:00 2001 From: Kevin Mehall Date: Mon, 2 Sep 2024 17:42:50 -0600 Subject: [PATCH 2/3] Stabilize waker_getters --- library/core/src/task/wake.rs | 8 ++++---- library/core/tests/lib.rs | 1 - 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/library/core/src/task/wake.rs b/library/core/src/task/wake.rs index 9baaa274bb071..8dc7e33aed363 100644 --- a/library/core/src/task/wake.rs +++ b/library/core/src/task/wake.rs @@ -552,7 +552,7 @@ impl Waker { /// Gets the `data` pointer used to create this `Waker`. #[inline] #[must_use] - #[unstable(feature = "waker_getters", issue = "96992")] + #[stable(feature = "waker_getters", since = "CURRENT_RUSTC_VERSION")] pub fn data(&self) -> *const () { self.waker.data } @@ -560,7 +560,7 @@ impl Waker { /// Gets the `vtable` pointer used to create this `Waker`. #[inline] #[must_use] - #[unstable(feature = "waker_getters", issue = "96992")] + #[stable(feature = "waker_getters", since = "CURRENT_RUSTC_VERSION")] pub fn vtable(&self) -> &'static RawWakerVTable { self.waker.vtable } @@ -826,7 +826,7 @@ impl LocalWaker { /// Gets the `data` pointer used to create this `LocalWaker`. #[inline] #[must_use] - #[unstable(feature = "waker_getters", issue = "96992")] + #[unstable(feature = "local_waker", issue = "118959")] pub fn data(&self) -> *const () { self.waker.data } @@ -834,7 +834,7 @@ impl LocalWaker { /// Gets the `vtable` pointer used to create this `LocalWaker`. #[inline] #[must_use] - #[unstable(feature = "waker_getters", issue = "96992")] + #[unstable(feature = "local_waker", issue = "118959")] pub fn vtable(&self) -> &'static RawWakerVTable { self.waker.vtable } diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index c205f028dd3a7..96fc621494f2a 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -112,7 +112,6 @@ #![feature(unsize)] #![feature(unsized_tuple_coercion)] #![feature(unwrap_infallible)] -#![feature(waker_getters)] // tidy-alphabetical-end #![allow(internal_features)] #![deny(fuzzy_provenance_casts)] From 22bd31977294f0c948409ec24034895f14b59ade Mon Sep 17 00:00:00 2001 From: Kevin Mehall Date: Mon, 2 Sep 2024 18:25:09 -0600 Subject: [PATCH 3/3] Add `Waker::new` and `LocalWaker::new` Per the `waker_getters` FCP: https://github.com/rust-lang/rust/issues/96992#issuecomment-1941998046 Docs largely copied from `RawWaker::new`. --- library/core/src/task/wake.rs | 55 +++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/library/core/src/task/wake.rs b/library/core/src/task/wake.rs index 8dc7e33aed363..6924b3c13ece3 100644 --- a/library/core/src/task/wake.rs +++ b/library/core/src/task/wake.rs @@ -493,6 +493,37 @@ impl Waker { a_data == b_data && ptr::eq(a_vtable, b_vtable) } + /// Creates a new `Waker` from the provided `data` pointer and `vtable`. + /// + /// The `data` pointer can be used to store arbitrary data as required + /// by the executor. This could be e.g. a type-erased pointer to an `Arc` + /// that is associated with the task. + /// The value of this pointer will get passed to all functions that are part + /// of the `vtable` as the first parameter. + /// + /// It is important to consider that the `data` pointer must point to a + /// thread safe type such as an `Arc`. + /// + /// The `vtable` customizes the behavior of a `Waker`. For each operation + /// on the `Waker`, the associated function in the `vtable` will be called. + /// + /// # Safety + /// + /// The behavior of the returned `Waker` is undefined if the contract defined + /// in [`RawWakerVTable`]'s documentation is not upheld. + /// + /// (Authors wishing to avoid unsafe code may implement the [`Wake`] trait instead, at the + /// cost of a required heap allocation.) + /// + /// [`Wake`]: ../../alloc/task/trait.Wake.html + #[inline] + #[must_use] + #[stable(feature = "waker_getters", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "waker_getters", since = "CURRENT_RUSTC_VERSION")] + pub const unsafe fn new(data: *const (), vtable: &'static RawWakerVTable) -> Self { + Waker { waker: RawWaker { data, vtable } } + } + /// Creates a new `Waker` from [`RawWaker`]. /// /// # Safety @@ -770,6 +801,30 @@ impl LocalWaker { a_data == b_data && ptr::eq(a_vtable, b_vtable) } + /// Creates a new `LocalWaker` from the provided `data` pointer and `vtable`. + /// + /// The `data` pointer can be used to store arbitrary data as required + /// by the executor. This could be e.g. a type-erased pointer to an `Arc` + /// that is associated with the task. + /// The value of this pointer will get passed to all functions that are part + /// of the `vtable` as the first parameter. + /// + /// The `vtable` customizes the behavior of a `LocalWaker`. For each + /// operation on the `LocalWaker`, the associated function in the `vtable` + /// will be called. + /// + /// # Safety + /// + /// The behavior of the returned `Waker` is undefined if the contract defined + /// in [`RawWakerVTable`]'s documentation is not upheld. + /// + #[inline] + #[must_use] + #[unstable(feature = "local_waker", issue = "118959")] + pub const unsafe fn new(data: *const (), vtable: &'static RawWakerVTable) -> Self { + LocalWaker { waker: RawWaker { data, vtable } } + } + /// Creates a new `LocalWaker` from [`RawWaker`]. /// /// The behavior of the returned `LocalWaker` is undefined if the contract defined