Remove some unsafe code (#540)
This commit is contained in:
parent
fd1d6a388d
commit
5aa77979d1
@ -65,11 +65,8 @@ impl TaskPool {
|
||||
{
|
||||
let executor = async_executor::LocalExecutor::new();
|
||||
|
||||
let executor: &async_executor::LocalExecutor = &executor;
|
||||
let executor: &'scope async_executor::LocalExecutor = unsafe { mem::transmute(executor) };
|
||||
|
||||
let mut scope = Scope {
|
||||
executor,
|
||||
executor: &executor,
|
||||
results: Vec::new(),
|
||||
};
|
||||
|
||||
@ -87,26 +84,18 @@ impl TaskPool {
|
||||
}
|
||||
|
||||
pub struct Scope<'scope, T> {
|
||||
executor: &'scope async_executor::LocalExecutor,
|
||||
executor: &'scope async_executor::LocalExecutor<'scope>,
|
||||
// Vector to gather results of all futures spawned during scope run
|
||||
results: Vec<Arc<Mutex<Option<T>>>>,
|
||||
}
|
||||
|
||||
impl<'scope, T: Send + 'static> Scope<'scope, T> {
|
||||
impl<'scope, T: Send + 'scope> Scope<'scope, T> {
|
||||
pub fn spawn<Fut: Future<Output = T> + 'scope + Send>(&mut self, f: Fut) {
|
||||
let result = Arc::new(Mutex::new(None));
|
||||
self.results.push(result.clone());
|
||||
let f = async move {
|
||||
result.lock().unwrap().replace(f.await);
|
||||
};
|
||||
|
||||
// SAFETY: This function blocks until all futures complete, so we do not read/write the
|
||||
// data from futures outside of the 'scope lifetime. However, rust has no way of knowing
|
||||
// this so we must convert to 'static here to appease the compiler as it is unable to
|
||||
// validate safety.
|
||||
let fut: Pin<Box<dyn Future<Output = ()> + 'scope>> = Box::pin(f);
|
||||
let fut: Pin<Box<dyn Future<Output = ()> + 'static>> = unsafe { mem::transmute(fut) };
|
||||
|
||||
self.executor.spawn(fut).detach();
|
||||
self.executor.spawn(f).detach();
|
||||
}
|
||||
}
|
||||
|
@ -38,8 +38,7 @@ impl<T> Task<T> {
|
||||
impl<T> Future for Task<T> {
|
||||
type Output = T;
|
||||
|
||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
// Safe because Task is pinned and contains async_executor::Task by value
|
||||
unsafe { self.map_unchecked_mut(|x| &mut x.0).poll(cx) }
|
||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
Pin::new(&mut self.0).poll(cx)
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ use std::{
|
||||
thread::{self, JoinHandle},
|
||||
};
|
||||
|
||||
use futures_lite::future;
|
||||
use futures_lite::{future, pin};
|
||||
|
||||
/// Used to create a TaskPool
|
||||
#[derive(Debug, Default, Clone)]
|
||||
@ -180,12 +180,8 @@ impl TaskPool {
|
||||
results
|
||||
};
|
||||
|
||||
// Move the value to ensure that it is owned
|
||||
let mut fut = fut;
|
||||
|
||||
// Shadow the original binding so that it can't be directly accessed
|
||||
// ever again.
|
||||
let fut = unsafe { Pin::new_unchecked(&mut fut) };
|
||||
// Pin the future on the stack.
|
||||
pin!(fut);
|
||||
|
||||
// SAFETY: This function blocks until all futures complete, so we do not read/write the
|
||||
// data from futures outside of the 'scope lifetime. However, rust has no way of knowing
|
||||
|
Loading…
Reference in New Issue
Block a user