Skip to content

Commit b6aa476

Browse files
authored
Merge pull request #2 from hymm/pool-intern-experiment
Fix stealing
2 parents 2f65f20 + fedb3a4 commit b6aa476

File tree

1 file changed

+19
-37
lines changed

1 file changed

+19
-37
lines changed

crates/bevy_tasks/src/task_pool.rs

Lines changed: 19 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
use std::{
22
future::Future,
33
mem,
4-
pin::Pin,
54
sync::Arc,
65
thread::{self, JoinHandle},
76
};
87

9-
use futures_lite::{future, pin, FutureExt};
8+
use futures_lite::{future, FutureExt};
109

1110
use crate::{Task, TaskGroup};
1211

@@ -303,8 +302,13 @@ impl TaskPool {
303302
let shutdown_rx = shutdown_rx.clone();
304303
make_thread_builder(&builder, "Compute", i)
305304
.spawn(move || {
305+
let future = async {
306+
loop {
307+
compute.tick().await;
308+
}
309+
};
306310
// Use unwrap_err because we expect a Closed error
307-
future::block_on(compute.run(shutdown_rx.recv())).unwrap_err();
311+
future::block_on(shutdown_rx.recv().or(future)).unwrap_err();
308312
})
309313
.expect("Failed to spawn thread.")
310314
})
@@ -322,7 +326,7 @@ impl TaskPool {
322326
}
323327
};
324328
// Use unwrap_err because we expect a Closed error
325-
future::block_on(future.or(shutdown_rx.recv())).unwrap_err();
329+
future::block_on(shutdown_rx.recv().or(future)).unwrap_err();
326330
})
327331
.expect("Failed to spawn thread.")
328332
})
@@ -341,7 +345,7 @@ impl TaskPool {
341345
}
342346
};
343347
// Use unwrap_err because we expect a Closed error
344-
future::block_on(future.or(shutdown_rx.recv())).unwrap_err();
348+
future::block_on(shutdown_rx.recv().or(future)).unwrap_err();
345349
})
346350
.expect("Failed to spawn thread.")
347351
})
@@ -436,12 +440,8 @@ impl TaskPool {
436440

437441
f(&mut scope);
438442

439-
if scope.spawned.is_empty() {
440-
Vec::default()
441-
} else if scope.spawned.len() == 1 {
442-
vec![future::block_on(&mut scope.spawned[0])]
443-
} else {
444-
let fut = async move {
443+
future::block_on(async move {
444+
let get_results = async move {
445445
let mut results = Vec::with_capacity(scope.spawned.len());
446446
for task in scope.spawned {
447447
results.push(task.await);
@@ -450,32 +450,14 @@ impl TaskPool {
450450
results
451451
};
452452

453-
// Pin the futures on the stack.
454-
pin!(fut);
455-
456-
// SAFETY: This function blocks until all futures complete, so we do not read/write
457-
// the data from futures outside of the 'scope lifetime. However,
458-
// rust has no way of knowing this so we must convert to 'static
459-
// here to appease the compiler as it is unable to validate safety.
460-
let fut: Pin<&mut (dyn Future<Output = Vec<T>>)> = fut;
461-
let fut: Pin<&'static mut (dyn Future<Output = Vec<T>> + 'static)> =
462-
unsafe { mem::transmute(fut) };
463-
464-
// The thread that calls scope() will participate in driving tasks in the pool
465-
// forward until the tasks that are spawned by this scope() call
466-
// complete. (If the caller of scope() happens to be a thread in
467-
// this thread pool, and we only have one thread in the pool, then
468-
// simply calling future::block_on(spawned) would deadlock.)
469-
let mut spawned = local_executor.spawn(fut);
470-
loop {
471-
if let Some(result) = future::block_on(future::poll_once(&mut spawned)) {
472-
break result;
473-
};
474-
475-
executor.try_tick();
476-
local_executor.try_tick();
477-
}
478-
}
453+
let tick_forever = async move {
454+
loop {
455+
local_executor.tick().or(executor.tick()).await;
456+
}
457+
};
458+
459+
get_results.or(tick_forever).await
460+
})
479461
})
480462
}
481463

0 commit comments

Comments
 (0)