Use new run_without_applying_deferred method in SingleThreadedExecutor (#18684)

# Objective

Simplify code in the `SingleThreadedExecutor` by removing a special case
for exclusive systems.

The `SingleThreadedExecutor` runs systems without immediately applying
deferred buffers. That required calling `run_unsafe()` instead of
`run()`, but that would `panic` for exclusive systems, so the code also
needed a special case for those. Following #18076 and #18406, we have a
`run_without_applying_deferred` method that has the exact behavior we
want and works on exclusive systems.

## Solution

Replace the code in `SingleThreadedExecutor` that runs systems with a
single call to `run_without_applying_deferred()`. Also add this as a
wrapper in the `__rust_begin_short_backtrace` module to preserve the
special behavior for backtraces.
This commit is contained in:
Chris Russell 2025-05-05 20:09:02 -04:00 committed by GitHub
parent 49f1827633
commit 3442e2556d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 32 additions and 32 deletions

View File

@ -271,38 +271,54 @@ impl IntoSystemSet<()> for ApplyDeferred {
mod __rust_begin_short_backtrace {
use core::hint::black_box;
#[cfg(feature = "std")]
use crate::world::unsafe_world_cell::UnsafeWorldCell;
use crate::{
error::Result,
system::{ReadOnlySystem, ScheduleSystem},
world::{unsafe_world_cell::UnsafeWorldCell, World},
world::World,
};
/// # Safety
/// See `System::run_unsafe`.
// This is only used by `MultiThreadedExecutor`, and would be dead code without `std`.
#[cfg(feature = "std")]
#[inline(never)]
pub(super) unsafe fn run_unsafe(system: &mut ScheduleSystem, world: UnsafeWorldCell) -> Result {
let result = system.run_unsafe((), world);
// Call `black_box` to prevent this frame from being tail-call optimized away
black_box(());
result
}
/// # Safety
/// See `ReadOnlySystem::run_unsafe`.
#[cfg_attr(
not(feature = "std"),
expect(dead_code, reason = "currently only used with the std feature")
)]
// This is only used by `MultiThreadedExecutor`, and would be dead code without `std`.
#[cfg(feature = "std")]
#[inline(never)]
pub(super) unsafe fn readonly_run_unsafe<O: 'static>(
system: &mut dyn ReadOnlySystem<In = (), Out = O>,
world: UnsafeWorldCell,
) -> O {
// Call `black_box` to prevent this frame from being tail-call optimized away
black_box(system.run_unsafe((), world))
}
#[inline(never)]
pub(super) fn run(system: &mut ScheduleSystem, world: &mut World) -> Result {
let result = system.run((), world);
// Call `black_box` to prevent this frame from being tail-call optimized away
black_box(());
result
}
#[inline(never)]
pub(super) fn run_without_applying_deferred(
system: &mut ScheduleSystem,
world: &mut World,
) -> Result {
let result = system.run_without_applying_deferred((), world);
// Call `black_box` to prevent this frame from being tail-call optimized away
black_box(());
result
}
@ -312,6 +328,7 @@ mod __rust_begin_short_backtrace {
system: &mut dyn ReadOnlySystem<In = (), Out = O>,
world: &mut World,
) -> O {
// Call `black_box` to prevent this frame from being tail-call optimized away
black_box(system.run((), world))
}
}

View File

@ -128,8 +128,9 @@ impl SystemExecutor for SingleThreadedExecutor {
}
let f = AssertUnwindSafe(|| {
if system.is_exclusive() {
if let Err(err) = __rust_begin_short_backtrace::run(system, world) {
if let Err(err) =
__rust_begin_short_backtrace::run_without_applying_deferred(system, world)
{
error_handler(
err,
ErrorContext::System {
@ -138,24 +139,6 @@ impl SystemExecutor for SingleThreadedExecutor {
},
);
}
} else {
// Use run_unsafe to avoid immediately applying deferred buffers
let world = world.as_unsafe_world_cell();
system.update_archetype_component_access(world);
// SAFETY: We have exclusive, single-threaded access to the world and
// update_archetype_component_access is being called immediately before this.
unsafe {
if let Err(err) = __rust_begin_short_backtrace::run_unsafe(system, world) {
error_handler(
err,
ErrorContext::System {
name: system.name(),
last_run: system.get_last_run(),
},
);
}
};
}
});
#[cfg(feature = "std")]