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