Skip to content

Commit bc2decd

Browse files
committed
revert change to executor
1 parent 00cfef8 commit bc2decd

File tree

1 file changed

+32
-14
lines changed

1 file changed

+32
-14
lines changed

crates/bevy_tasks/src/task_pool.rs

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ use std::{
33
marker::PhantomData,
44
mem,
55
sync::Arc,
6-
thread::{self, JoinHandle},
6+
thread::{self, JoinHandle}, pin::Pin,
77
};
88

99
use concurrent_queue::ConcurrentQueue;
10-
use futures_lite::{future, FutureExt};
10+
use futures_lite::{future, pin};
1111

1212
use crate::Task;
1313

@@ -241,7 +241,9 @@ impl TaskPool {
241241

242242
f(scope_ref);
243243

244-
future::block_on(async move {
244+
if spawned.is_empty() {
245+
Vec::new()
246+
} else {
245247
let get_results = async move {
246248
let mut results = Vec::with_capacity(spawned.len());
247249
while let Ok(task) = spawned.pop() {
@@ -251,17 +253,33 @@ impl TaskPool {
251253
results
252254
};
253255

254-
let tick_forever = async move {
255-
loop {
256-
self.executor.try_tick();
257-
task_scope_executor.try_tick();
258-
259-
future::yield_now().await;
260-
}
261-
};
262-
263-
get_results.or(tick_forever).await
264-
})
256+
// Pin the futures on the stack.
257+
pin!(get_results);
258+
259+
// SAFETY: This function blocks until all futures complete, so we do not read/write
260+
// the data from futures outside of the 'scope lifetime. However,
261+
// rust has no way of knowing this so we must convert to 'static
262+
// here to appease the compiler as it is unable to validate safety.
263+
let get_results: Pin<&mut (dyn Future<Output = Vec<T>> + 'static + Send)> = get_results;
264+
let get_results: Pin<&'static mut (dyn Future<Output = Vec<T>> + 'static + Send)> =
265+
unsafe { mem::transmute(get_results) };
266+
267+
// The thread that calls scope() will participate in driving tasks in the pool
268+
// forward until the tasks that are spawned by this scope() call
269+
// complete. (If the caller of scope() happens to be a thread in
270+
// this thread pool, and we only have one thread in the pool, then
271+
// simply calling future::block_on(spawned) would deadlock.)
272+
let mut spawned = task_scope_executor.spawn(get_results);
273+
274+
loop {
275+
if let Some(result) = future::block_on(future::poll_once(&mut spawned)) {
276+
break result;
277+
};
278+
279+
self.executor.try_tick();
280+
task_scope_executor.try_tick();
281+
}
282+
}
265283
}
266284

267285
/// Spawns a static future onto the thread pool. The returned Task is a future. It can also be

0 commit comments

Comments
 (0)