Skip to content

Commit 2d658e9

Browse files
authored
Rollup merge of rust-lang#91828 - oxalica:feat/waker-getters, r=dtolnay
Implement `RawWaker` and `Waker` getters for underlying pointers implement rust-lang#87021 New APIs: - `RawWaker::data(&self) -> *const ()` - `RawWaker::vtable(&self) -> &'static RawWakerVTable` - ~`Waker::as_raw_waker(&self) -> &RawWaker`~ `Waker::as_raw(&self) -> &RawWaker` This third one is an auxiliary function to make the two APIs above more useful. Since we can only get `&Waker` in `Future::poll`, without this, we need to `transmute` it into `&RawWaker` (relying on `repr(transparent)`) in order to access its data/vtable pointers. ~Not sure if it should be named `as_raw` or `as_raw_waker`. Seems we always use `as_<something-raw>` instead of just `as_raw`. But `as_raw_waker` seems not quite consistent with `Waker::from_raw`.~ As suggested in rust-lang#91828 (comment), use `as_raw`.
2 parents a937dd5 + bae0da8 commit 2d658e9

File tree

3 files changed

+48
-0
lines changed

3 files changed

+48
-0
lines changed

library/core/src/task/wake.rs

+24
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,22 @@ impl RawWaker {
4343
pub const fn new(data: *const (), vtable: &'static RawWakerVTable) -> RawWaker {
4444
RawWaker { data, vtable }
4545
}
46+
47+
/// Get the `data` pointer used to create this `RawWaker`.
48+
#[inline]
49+
#[must_use]
50+
#[unstable(feature = "waker_getters", issue = "87021")]
51+
pub fn data(&self) -> *const () {
52+
self.data
53+
}
54+
55+
/// Get the `vtable` pointer used to create this `RawWaker`.
56+
#[inline]
57+
#[must_use]
58+
#[unstable(feature = "waker_getters", issue = "87021")]
59+
pub fn vtable(&self) -> &'static RawWakerVTable {
60+
self.vtable
61+
}
4662
}
4763

4864
/// A virtual function pointer table (vtable) that specifies the behavior
@@ -260,6 +276,14 @@ impl Waker {
260276
pub unsafe fn from_raw(waker: RawWaker) -> Waker {
261277
Waker { waker }
262278
}
279+
280+
/// Get a reference to the underlying [`RawWaker`].
281+
#[inline]
282+
#[must_use]
283+
#[unstable(feature = "waker_getters", issue = "87021")]
284+
pub fn as_raw(&self) -> &RawWaker {
285+
&self.waker
286+
}
263287
}
264288

265289
#[stable(feature = "futures_api", since = "1.36.0")]

library/core/tests/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@
9090
#![feature(unzip_option)]
9191
#![feature(const_array_from_ref)]
9292
#![feature(const_slice_from_ref)]
93+
#![feature(waker_getters)]
9394
#![deny(unsafe_op_in_unsafe_fn)]
9495

9596
extern crate test;
@@ -131,3 +132,4 @@ mod task;
131132
mod time;
132133
mod tuple;
133134
mod unicode;
135+
mod waker;

library/core/tests/waker.rs

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
use std::ptr;
2+
use std::task::{RawWaker, RawWakerVTable, Waker};
3+
4+
#[test]
5+
fn test_waker_getters() {
6+
let raw_waker = RawWaker::new(42usize as *mut (), &WAKER_VTABLE);
7+
assert_eq!(raw_waker.data() as usize, 42);
8+
assert!(ptr::eq(raw_waker.vtable(), &WAKER_VTABLE));
9+
10+
let waker = unsafe { Waker::from_raw(raw_waker) };
11+
let waker2 = waker.clone();
12+
let raw_waker2 = waker2.as_raw();
13+
assert_eq!(raw_waker2.data() as usize, 43);
14+
assert!(ptr::eq(raw_waker2.vtable(), &WAKER_VTABLE));
15+
}
16+
17+
static WAKER_VTABLE: RawWakerVTable = RawWakerVTable::new(
18+
|data| RawWaker::new((data as usize + 1) as *mut (), &WAKER_VTABLE),
19+
|_| {},
20+
|_| {},
21+
|_| {},
22+
);

0 commit comments

Comments
 (0)