Skip to main content

Module waiting

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 wake once 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 under forbid_commit_waits_strictly, whose code still reads the disk itself.
forbid_commit_waits_strictly
forbid_on_this_thread for 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_thread for a test: a blocking wait reached anyway panics, naming what waited.
forbidden
Whether this thread must not wait on storage.
observe
Tell observer about every storage wait reached on a thread that forbids them. One observer per process; false when one was installed already.
refused
The caller is about to wait on storage (what says 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
refused for a wait on another thread’s commit (a store’s writer committing and syncing): also fails a test marked with forbid_commit_waits_strictly.
same_wake
Whether a and b are 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: None where 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.