Я сделал этот простейший исполнитель блоков, но он требует небезопасности, и я не смог его удалить.
use core::future::Future;
use core::pin::Pin;
use core::task::{Context, Poll, RawWaker, RawWakerVTable, Waker};
// Create a no-op waker
fn dummy_raw_waker() -> RawWaker {
fn no_op_clone(_: *const ()) -> RawWaker {
dummy_raw_waker()
}
fn no_op(_: *const ()) {}
RawWaker::new(
core::ptr::null(),
&RawWakerVTable::new(no_op_clone, no_op, no_op, no_op),
)
}
// no dependency blocking function for debugging only
pub fn debug_only_unsafe_block_on<F: Future>(mut future: F) -> F::Output {
let waker = unsafe { Waker::from_raw(dummy_raw_waker()) };
let mut context = Context::from_waker(&waker);
// Pin the future on the stack
let mut future = unsafe { Pin::new_unchecked(&mut future) };
loop {
match future.as_mut().poll(&mut context) {
Poll::Ready(val) => return val,
Poll::Pending => {
// In a real system, you might yield to the executor or check other tasks,
// but in this simple case, we just keep polling.
}
}
}
}
Есть ли способ удалить ключевое слово unsafe? Цель состоит в том, чтобы больше не использовать зависимости в моем коде.
Вы можете реализовать черту Wake вручную и использовать макрос pin, чтобы избежать небезопасного кода.
#![deny(unsafe_code)]
use core::future::Future;
use core::task::{Context, Poll};
use std::pin::pin;
use std::sync::Arc;
use std::task::Wake;
struct NoOpWaker;
impl Wake for NoOpWaker {
fn wake(self: Arc<Self>) {}
}
// no dependency blocking function for debugging only
pub fn debug_only_safe_block_on<F: Future>(mut future: F) -> F::Output {
let waker = Arc::new(NoOpWaker).into();
let mut context = Context::from_waker(&waker);
let mut future = pin!(future);
loop {
match future.as_mut().poll(&mut context) {
Poll::Ready(val) => return val,
Poll::Pending => {
// In a real system, you might yield to the executor or check other tasks,
// but in this simple case, we just keep polling.
}
}
}
}
async fn foo() -> i32 {
1
}
fn main() {
let data = debug_only_safe_block_on(foo());
assert_eq!(1, data);
}
По сути, это настолько мало, насколько это возможно: docs.rs/pollster/latest/src/pollster/lib.rs.html