diff --git a/library/core/src/task/wake.rs b/library/core/src/task/wake.rs index 6cba781c2ed8f..27af227a1f27f 100644 --- a/library/core/src/task/wake.rs +++ b/library/core/src/task/wake.rs @@ -43,6 +43,22 @@ impl RawWaker { pub const fn new(data: *const (), vtable: &'static RawWakerVTable) -> RawWaker { RawWaker { data, vtable } } + + /// Get the `data` pointer used to create this `RawWaker`. + #[inline] + #[must_use] + #[unstable(feature = "waker_getters", issue = "87021")] + pub fn data(&self) -> *const () { + self.data + } + + /// Get the `vtable` pointer used to create this `RawWaker`. + #[inline] + #[must_use] + #[unstable(feature = "waker_getters", issue = "87021")] + pub fn vtable(&self) -> &'static RawWakerVTable { + self.vtable + } } /// A virtual function pointer table (vtable) that specifies the behavior @@ -260,6 +276,14 @@ impl Waker { pub unsafe fn from_raw(waker: RawWaker) -> Waker { Waker { waker } } + + /// Get a reference to the underlying [`RawWaker`]. + #[inline] + #[must_use] + #[unstable(feature = "waker_getters", issue = "87021")] + pub fn as_raw(&self) -> &RawWaker { + &self.waker + } } #[stable(feature = "futures_api", since = "1.36.0")] diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index 012e6e5b57ad0..40d4fa60d0bc7 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -81,6 +81,7 @@ #![feature(unzip_option)] #![feature(const_array_from_ref)] #![feature(const_slice_from_ref)] +#![feature(waker_getters)] #![deny(unsafe_op_in_unsafe_fn)] extern crate test; @@ -121,3 +122,4 @@ mod task; mod time; mod tuple; mod unicode; +mod waker; diff --git a/library/core/tests/waker.rs b/library/core/tests/waker.rs new file mode 100644 index 0000000000000..6602ab36ba714 --- /dev/null +++ b/library/core/tests/waker.rs @@ -0,0 +1,22 @@ +use std::ptr; +use std::task::{RawWaker, RawWakerVTable, Waker}; + +#[test] +fn test_waker_getters() { + let raw_waker = RawWaker::new(42usize as *mut (), &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) }; + 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)); +} + +static WAKER_VTABLE: RawWakerVTable = RawWakerVTable::new( + |data| RawWaker::new((data as usize + 1) as *mut (), &WAKER_VTABLE), + |_| {}, + |_| {}, + |_| {}, +);