72 lines
3.1 KiB
Markdown
72 lines
3.1 KiB
Markdown
|
# 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):
|
||
|
<pre>
|
||
|
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
|
||
|
}
|
||
|
</pre>
|
||
|
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.
|