diff --git a/src/runtime/block_on.rs b/src/runtime/block_on.rs index 34f0dfa..c7bbd31 100644 --- a/src/runtime/block_on.rs +++ b/src/runtime/block_on.rs @@ -7,8 +7,7 @@ use std::task::{Context, Poll, Waker}; /// Start the event loop. Blocks until the future pub fn block_on(fut: F) -> F::Output where - F: Future + 'static, - F::Output: 'static, + F: Future, { // Construct the reactor let reactor = Reactor::new(); @@ -19,7 +18,11 @@ where } // Spawn the task onto the reactor. - let root_task = reactor.spawn(fut); + // Safety: The execution loop below, concluding with pulling the Ready out + // of the root_task, ensures that it does not outlive the Future or its + // output. + #[allow(unsafe_code)] + let root_task = unsafe { reactor.spawn_unchecked(fut) }; loop { match reactor.pop_ready_list() { diff --git a/src/runtime/reactor.rs b/src/runtime/reactor.rs index ba78fd9..32dc073 100644 --- a/src/runtime/reactor.rs +++ b/src/runtime/reactor.rs @@ -258,11 +258,17 @@ impl Reactor { ready } - /// Spawn a `Task` on the `Reactor`. - pub fn spawn(&self, fut: F) -> Task + /// We need an unchecked spawn for implementing `block_on`, where the + /// implementation does not expose the resulting Task and does not return + /// until all tasks have finished execution. + /// + /// # Safety + /// Caller must ensure that the Task does not outlive the Future F or + /// F::Output T. + #[allow(unsafe_code)] + pub(crate) unsafe fn spawn_unchecked(&self, fut: F) -> Task where - F: Future + 'static, - T: 'static, + F: Future, { let this = self.clone(); let schedule = move |runnable| this.inner.ready_list.lock().unwrap().push_back(runnable); @@ -278,6 +284,19 @@ impl Reactor { task } + /// Spawn a `Task` on the `Reactor`. + pub fn spawn(&self, fut: F) -> Task + where + F: Future + 'static, + T: 'static, + { + // Safety: 'static constraints satisfy the lifetime requirements + #[allow(unsafe_code)] + unsafe { + self.spawn_unchecked(fut) + } + } + pub(super) fn pop_ready_list(&self) -> Option { self.inner.ready_list.lock().unwrap().pop_front() }