blob: 114b7a7c92204eb8fbc7924c63741293634acf33 [file] [log] [blame] [view]
<?% config.freshness.owner = 'hta' %?>
<?% config.freshness.reviewed = '2021-05-31' %?>
# Basic concepts and primitives
## Time
Internally, time is represent using the [webrtc::Timestamp][1] class. This
represents
time with a resolution of one microsecond, using a 64-bit integer, and provides
converters to milliseconds or seconds as needed.
All timestamps need to be measured from the system monotonic time.
The epoch is not specified (because we can't always know if the system clock is
correct), but whenever an absolute epoch is needed, the Unix time
epoch (Jan 1, 1970 at 0:00 GMT) is used.
Conversion from/to other formats (for example milliseconds, NTP times,
timestamp strings) should happen as close to the interface requiring that
format as possible.
NOTE: There are parts of the codebase that don't use Timestamp, parts of the
codebase that use the NTP epoch, and parts of the codebase that don't use the
monotonic clock. They need to
be updated.
## Threads
All execution happens on a TaskQueue instance. How a TaskQueue is implemented
varies by platform, but they all have the [webrtc::TaskQueueBase][3] API.
This API offers primitives for posting tasks, with or without delay.
Some core parts use the [rtc::Thread][2], which is a subclass of TaskQueueBase.
This may contain a SocketServer for processing I/O, and is used for policing
certain calling pattern between a few core threads (the NetworkThread cannot
do Invoke on the Worker thread, for instance).
## Synchronization primitives
### PostTask and thread-guarded variables
The preferred method for synchronization is to post tasks between threads,
and to let each thread take care of its own variables (lock-free programming).
All variables in
classes intended to be used with multiple threads should therefore be
annotated with RTC_GUARDED_BY(thread).
For classes used with only one thread, the recommended pattern is to let
them own a webrtc::SequenceChecker (conventionally named sequence_checker_)
and let all variables be RTC_GUARDED_BY(sequence_checker_).
Member variables marked const do not need to be guarded, since they never
change. (But note that they may point to objects that can change!)
When posting tasks with callbacks, it is the duty of the caller to check
that the object one is calling back into still exists when the callback
is made. A helper for this task is the [webrtc::ScopedTaskSafety][5]
flag, which can automatically drop callbacks in this situation, and
associated classes.
### Synchronization primitives to be used when needed
When it is absolutely necessary to let one thread wait for another thread
to do something, Thread::Invoke can be used. This function is DISCOURAGED,
since it leads to performance issues, but is currently still widespread.
When it is absolutely necessary to access one variable from multiple threads,
the webrtc::Mutex can be used. Such variables MUST be marked up with
RTC_GUARDED_BY(mutex), to allow static analysis that lessens the chance of
deadlocks or unintended consequences.
### Synchronization primitives that are being removed
The following non-exhaustive list of synchronization primitives are
in the (slow) process of being removed from the codebase.
* sigslot. Use [webrtc::CallbackList][4] instead, or, when there's only one
signal consumer, a single std::function.
* AsyncInvoker.
[1]: https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/api/units/timestamp.h;drc=b95d90b78a3491ef8e8aa0640dd521515ec881ca;l=29
[2]: https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/rtc_base/thread.h;drc=1107751b6f11c35259a1c5c8a0f716e227b7e3b4;l=194
[3]: https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/api/task_queue/task_queue_base.h;drc=1107751b6f11c35259a1c5c8a0f716e227b7e3b4;l=25
[4]: https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/rtc_base/callback_list.h;drc=54b91412de3f579a2d5ccdead6e04cc2cc5ca3a1;l=162
[5]: https://source.chromium.org/chromium/chromium/src/+/main:third_party/webrtc/rtc_base/task_utils/pending_task_safety_flag.h;drc=86ee89f73e4f4799b3ebcc0b5c65837c9601fe6d;l=117