未验证 提交 a643e598 编写于 作者: M Matthias Krüger 提交者: GitHub

Rollup merge of #91828 - oxalica:feat/waker-getters, r=dtolnay

Implement `RawWaker` and `Waker` getters for underlying pointers

implement #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 https://github.com/rust-lang/rust/pull/91828#discussion_r770729837, use `as_raw`.
......@@ -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 @@ pub fn will_wake(&self, other: &Waker) -> bool {
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")]
......
......@@ -90,6 +90,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;
......@@ -131,3 +132,4 @@
mod time;
mod tuple;
mod unicode;
mod waker;
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),
|_| {},
|_| {},
|_| {},
);
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册