Module waiting
Expand description
Threads that must never wait on storage.
A compositor’s frame loop that waits for a store’s commit, an fsync on
another thread, is a frozen desktop for as long as the disk takes: on a
busy machine that is seconds. Such a thread says so with
forbid_on_this_thread; from then until the guard drops, callers
that would otherwise ask for a durable barrier
(crate::DurableStore::flush_where_allowed) only start the commit and
learn of its outcome later, through crate::DurableStore::durability,
and code that would wait on the disk itself (an app the compositor hosts
listing a folder) does it on a worker.
A blocking call still reached on such a thread, such as a store’s
crate::DurableStore::flush, reports it through refused: to the observer the process
installed (observe, which a compositor’s audit lists), and, on a
thread a test marked with forbid_strictly_on_this_thread, as a panic,
so the test names the caller.
Work such a thread would have waited for is done for it elsewhere (a
store’s own thread opening or reading a key) while it is told “not yet”.
The thread’s wake (Forbidden::waking, decline_on_this_thread:
for a frame loop, its redraw) is how it hears that the work is done, so
an idle thread asks again without polling; wake hands it to whoever
does that work.
A commit wait (refused_commit: waiting for another thread’s fsync)
is the one a frame loop can never bound, and the one a caller can always
avoid by asking durability instead. A test of code that still reads the
disk on its thread marks it with forbid_commit_waits_strictly: reads
are reported as usual, and only a commit wait fails the test.
Structs§
- Forbidden
- Keeps storage waits forbidden on the thread that made it, until dropped.
Not
Send: it belongs to that thread.
Functions§
- decline_
on_ this_ thread - From now on, have stores do this thread’s disk work (opening, reading)
elsewhere and answer “not yet”, waking it through
wakeonce the work is done: for a frame loop, before its loop forbids every wait (forbid_on_this_thread). Its own waits, such as a flush it asks for, stay allowed. For the rest of the thread’s life, or until a guard made before this drops; a forbidden thread keeps its rule and takes the new wake. - disk_
forbidden - Whether this thread must not touch the disk at all, so a store does its
disk work elsewhere and answers “not yet” (
wake): a thread that declined it, and every forbidden thread but one underforbid_commit_waits_strictly, whose code still reads the disk itself. - forbid_
commit_ waits_ strictly forbid_on_this_threadfor a test of code that still reads the disk here: a commit wait reached anyway panics, naming what waited, and other waits are only reported.- forbid_
on_ this_ thread - Forbid storage waits on this thread while the guard lives. See the module docs.
- forbid_
strictly_ on_ this_ thread forbid_on_this_threadfor a test: a blocking wait reached anyway panics, naming what waited.- forbidden
- Whether this thread must not wait on storage.
- observe
- Tell
observerabout every storage wait reached on a thread that forbids them. One observer per process;falsewhen one was installed already. - refused
- The caller is about to wait on storage (
whatsays on what): a store’s commit, or the disk itself, such as listing a folder. Where waits are forbidden the observer hears of it, and a strict test fails, naming the caller. - refused_
commit refusedfor a wait on another thread’s commit (a store’s writer committing and syncing): also fails a test marked withforbid_commit_waits_strictly.- same_
wake - Whether
aandbare the same wake, so it is called once however often the thread asked. - wake
- How to wake this thread once work it must not wait for is done:
Nonewhere it may touch the disk (disk_forbidden). A thread that set no wake gets one that does nothing; it hears of the work only when it next asks.