Name the executors and fail a block_on on the UI thread

architecture.md §7.1 stated five executors and their thread counts, and
no code named them. dr_ui::executors now does: the Executor enum with
each one's thread name and the count §7.1 gives with its reason, and
spawn, which starts a thread named <executor>:<role> and marks it with
the executor it belongs to. The counts are the stated budget, not yet a
bound: a job still gets a thread of its own when it starts.

run marks its own thread as the UI executor before it builds the
window. net_runtime::build now returns a NetRuntime whose block_on
asserts, in debug and test builds, that the caller is not that thread;
everything else derefs to the tokio runtime. The login, folder-list and
remote-folder workers built the same runtime by hand and now take it
from net_runtime, so their block_on is guarded too.

Tests: a block_on on a thread marked as the UI executor panics naming
the UI thread; the same call on a worker returns; a spawned thread
carries its name and executor.
This commit is contained in:
2026-09-27 07:08:37 -04:00
parent c50d96e949
commit 7be1efff32
5 changed files with 292 additions and 25 deletions
+5
View File
@@ -33,6 +33,7 @@ mod develop_ui;
mod display_ui;
mod duplicates;
mod duplicates_ui;
pub mod executors;
mod export;
pub mod faces;
mod folder_dialog;
@@ -1142,6 +1143,10 @@ fn shared_gpu() -> Option<dr_gpu::GpuContext> {
/// TRACES: M-13 | M-14
/// Build and run the viewer.
pub fn run(paths: Vec<PathBuf>) -> Result<()> {
// This thread creates the window and enters Slint's event loop: it is the
// UI executor, and every blocking helper asserts it is not (NFR-ARCH-1).
executors::mark_ui_thread();
// Mutable because the browsing list has two sources: the command line at
// startup, and whatever the library grid is showing when a cell is
// clicked. Opening from the grid replaces this so next/previous walk the