diff options
Diffstat (limited to '')
-rw-r--r-- | third_party/libwebrtc/api/g3doc/threading_design.md | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/third_party/libwebrtc/api/g3doc/threading_design.md b/third_party/libwebrtc/api/g3doc/threading_design.md new file mode 100644 index 0000000000..8023b5eda0 --- /dev/null +++ b/third_party/libwebrtc/api/g3doc/threading_design.md @@ -0,0 +1,74 @@ +<!-- go/cmark --> +<!--* freshness: {owner: 'hta' reviewed: '2021-04-12'} *--> + +# API Threading Design considerations + +The header files in this directory form the API to the WebRTC library +that is intended for client applications' use. + +This API is designed to be used on top of a multithreaded runtime. + +The public API functions are designed to be called from a single thread* +(the "client thread"), and can do internal dispatching to the thread +where activity needs to happen. Those threads can be passed in by the +client, typically as arguments to factory constructors, or they can be +created by the library if factory constructors that don't take threads +are used. + +Many of the functions are designed to be used in an asynchronous manner, +where a function is called to initiate an activity, and a callback will +be called when the activity is completed, or a handler function will +be called on an observer object when interesting events happen. + +Note: Often, even functions that look like simple functions (such as +information query functions) will need to jump between threads to perform +their function - which means that things may happen on other threads +between calls; writing "increment(x); increment(x)" is not a safe +way to increment X by exactly two, since the increment function may have +jumped to another thread that already had a queue of things to handle, +causing large amounts of other activity to have intervened between +the two calls. + +(*) The term "thread" is used here to denote any construct that guarantees +sequential execution - other names for such constructs are task runners +and sequenced task queues. + +## Client threads and callbacks + +At the moment, the API does not give any guarantee on which thread* the +callbacks and events are called on. So it's best to write all callback +and event handlers like this (pseudocode): +``` +void ObserverClass::Handler(event) { + if (!called_on_client_thread()) { + dispatch_to_client_thread(bind(handler(event))); + return; + } + // Process event, we're now on the right thread +} +``` +In the future, the implementation may change to always call the callbacks +and event handlers on the client thread. + +## Implementation considerations + +The C++ classes that are part of the public API are also used to derive +classes that form part of the implementation. + +This should not directly concern users of the API, but may matter if one +wants to look at how the WebRTC library is implemented, or for legacy code +that directly accesses internal APIs. + +Many APIs are defined in terms of a "proxy object", which will do a blocking +dispatch of the function to another thread, and an "implementation object" +which will do the actual +work, but can only be created, invoked and destroyed on its "home thread". + +Usually, the classes are named "xxxInterface" (in api/), "xxxProxy" and +"xxx" (not in api/). WebRTC users should only need to depend on the files +in api/. In many cases, the "xxxProxy" and "xxx" classes are subclasses +of "xxxInterface", but this property is an implementation feature only, +and should not be relied upon. + +The threading properties of these internal APIs are NOT documented in +this note, and need to be understood by inspecting those classes. |