0

[Threading and Tasks] Add Nomenclature section to docs

We get frequent questions about these terms and it's time we document
them explicitly. "thread-compatible" is a new term we haven't used in
the past (we just used initialized-once-read-only-forever-after)
but let's use that from now on as it's more consistent with the
internal docs:
https://engdoc.corp.google.com/eng/doc/devguide/cpp/primer.md?cl=head#thread_safety

R=fdoray@chromium.org

Change-Id: Ia20eadfb1910d54524bd0c08eb70dd60d94eae39
Reviewed-on: https://chromium-review.googlesource.com/c/1456642
Auto-Submit: Gabriel Charette <gab@chromium.org>
Commit-Queue: François Doray <fdoray@chromium.org>
Reviewed-by: François Doray <fdoray@chromium.org>
Cr-Commit-Position: refs/heads/master@{#629730}
This commit is contained in:
Gabriel Charette
2019-02-06 21:12:15 +00:00
committed by Commit Bot
parent 62bb74b599
commit 364a16a771

@ -15,6 +15,32 @@ objects. Instead, objects live on only one thread, we pass messages between
threads for communication, and we use callback interfaces (implemented by
message passing) for most cross-thread requests.
### Nomenclature
* **Thread-unsafe**: The vast majority of types in Chrome are thread-unsafe by
design. Such types/methods cannot be accessed concurrently from different
threads. They should either be accessed from a single
`base::SequencedTaskRunner` (this should be enforced by a `SEQUENCE_CHECKER`)
or be accessed with external synchronization (e.g. locks -- but
[prefer sequences](#Using-Sequences-Instead-of-Locks)).
* **Thread-affine**: Such types/methods need to be always accessed from the
same physical thread (i.e. from the same `base::SingleThreadTaskRunner`).
Short of using a third-party API or having a leaf dependency which is
thread-affine: there's pretty much no reason for a type to be thread-affine
in Chrome. Note that `base::SingleThreadTaskRunner` is-a
`base::SequencedTaskRunner` so thread-affine is a subset of thread-unsafe.
* **Thread-safe**: Such types/methods can be safely accessed concurrently.
* **Thread-compatible**: Such types/methods are initialized once in a
thread-safe manner (either in the single-threaded phase of startup or lazily
through a thread-safe static-local-initialization paradigm a la
`base::NoDestructor`) and can forever after be accessed concurrently in a
read-only manner.
* **Sequence-friendly**: Such types/methods are thread-unsafe types which
support being invoked from a `base::SequencedTaskRunner`. Ideally this would
be the case for all thread-unsafe types but legacy code sometimes has
overzealous checks that enforce thread-affinity in mere thread-unsafe
scenarios. See [Prefer Sequences to Threads](#prefer-sequences-to-threads)
below for more details.
### Threads
Every Chrome process has
@ -70,9 +96,10 @@ availability (increased parallelism on bigger machines, avoids trashing
resources on smaller machines).
Many core APIs were recently made sequence-friendly (classes are rarely
thread-affine -- i.e. only when using thread-local-storage or third-party APIs
that do). But the codebase has long evolved assuming single-threaded contexts...
If your class could run on a sequence but is blocked by an overzealous use of
thread-affine -- i.e. only when using third-party APIs that are thread-affine;
even ThreadLocalStorage has a SequenceLocalStorage equivalent). But the codebase
has long evolved assuming single-threaded contexts... If your class could run on
a sequence but is blocked by an overzealous use of
ThreadChecker/ThreadTaskRunnerHandle/SingleThreadTaskRunner in a leaf
dependency, consider fixing that dependency for everyone's benefit (or at the
very least file a blocking bug against https://crbug.com/675631 and flag your