blob: 8023b5eda071662b4826872af5c8eafa3b429664 [file] [log] [blame] [view]
Artem Titova6178672023-01-30 10:51:011<!-- go/cmark -->
2<!--* freshness: {owner: 'hta' reviewed: '2021-04-12'} *-->
3
Harald Alvestrand4af6f2b2021-04-12 11:47:564# API Threading Design considerations
Harald Alvestrandf3301832019-06-03 07:45:115
6The header files in this directory form the API to the WebRTC library
7that is intended for client applications' use.
8
9This API is designed to be used on top of a multithreaded runtime.
10
11The public API functions are designed to be called from a single thread*
12(the "client thread"), and can do internal dispatching to the thread
13where activity needs to happen. Those threads can be passed in by the
14client, typically as arguments to factory constructors, or they can be
15created by the library if factory constructors that don't take threads
16are used.
17
18Many of the functions are designed to be used in an asynchronous manner,
19where a function is called to initiate an activity, and a callback will
20be called when the activity is completed, or a handler function will
21be called on an observer object when interesting events happen.
22
23Note: Often, even functions that look like simple functions (such as
24information query functions) will need to jump between threads to perform
25their function - which means that things may happen on other threads
26between calls; writing "increment(x); increment(x)" is not a safe
27way to increment X by exactly two, since the increment function may have
28jumped to another thread that already had a queue of things to handle,
29causing large amounts of other activity to have intervened between
30the two calls.
31
32(*) The term "thread" is used here to denote any construct that guarantees
33sequential execution - other names for such constructs are task runners
34and sequenced task queues.
35
Harald Alvestrand4af6f2b2021-04-12 11:47:5636## Client threads and callbacks
Harald Alvestrandf3301832019-06-03 07:45:1137
38At the moment, the API does not give any guarantee on which thread* the
39callbacks and events are called on. So it's best to write all callback
40and event handlers like this (pseudocode):
Byoungchan Lee0c5a5ca2021-07-08 00:00:1941```
Harald Alvestrandf3301832019-06-03 07:45:1142void ObserverClass::Handler(event) {
43 if (!called_on_client_thread()) {
44 dispatch_to_client_thread(bind(handler(event)));
45 return;
46 }
47 // Process event, we're now on the right thread
48}
Byoungchan Lee0c5a5ca2021-07-08 00:00:1949```
Harald Alvestrandf3301832019-06-03 07:45:1150In the future, the implementation may change to always call the callbacks
51and event handlers on the client thread.
52
Harald Alvestrand4af6f2b2021-04-12 11:47:5653## Implementation considerations
Harald Alvestrandf3301832019-06-03 07:45:1154
55The C++ classes that are part of the public API are also used to derive
56classes that form part of the implementation.
57
58This should not directly concern users of the API, but may matter if one
59wants to look at how the WebRTC library is implemented, or for legacy code
60that directly accesses internal APIs.
61
62Many APIs are defined in terms of a "proxy object", which will do a blocking
63dispatch of the function to another thread, and an "implementation object"
64which will do the actual
65work, but can only be created, invoked and destroyed on its "home thread".
66
67Usually, the classes are named "xxxInterface" (in api/), "xxxProxy" and
68"xxx" (not in api/). WebRTC users should only need to depend on the files
69in api/. In many cases, the "xxxProxy" and "xxx" classes are subclasses
70of "xxxInterface", but this property is an implementation feature only,
71and should not be relied upon.
72
73The threading properties of these internal APIs are NOT documented in
74this note, and need to be understood by inspecting those classes.