Remove some unsafe code (#540)

This commit is contained in:
Stjepan Glavina 2020-09-21 22:13:40 +02:00 committed by GitHub
parent fd1d6a388d
commit 5aa77979d1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 9 additions and 25 deletions

View File

@ -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();
}
}

View File

@ -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)
}
}

View File

@ -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