Thread* MaybeWrapThread(Thread* signaling_thread, bool& wraps_current_thread) {
wraps_current_thread = false;
if (signaling_thread) { return signaling_thread;
} auto this_thread = Thread::Current();
if (!this_thread) { // If this thread isn't already wrapped by an webrtc::Thread, create a // wrapper and own it in this class.
this_thread = ThreadManager::Instance()->WrapCurrentThread();
wraps_current_thread = true;
} return this_thread;
}
// Access to the media engine operations is constrained to the worker thread. // This accessor via `MediaEngineReference` is provided to help ensure that a // reference is held and that the call is being issued on the worker thread.
MediaEngineInterface* ConnectionContext::MediaEngineReference::media_engine() const {
RTC_DCHECK_RUN_ON(c_->worker_thread());
RTC_DCHECK(c_->media_engine_w()); return c_->media_engine_w();
}
signaling_thread_->AllowInvokesToThread(worker_thread());
signaling_thread_->AllowInvokesToThread(network_thread_);
worker_thread_->AllowInvokesToThread(network_thread_);
if (!network_thread_->IsCurrent()) { // network_thread_->IsCurrent() == true means signaling_thread_ is // network_thread_. In this case, no further action is required as // signaling_thread_ can already invoke network_thread_.
network_thread_->PostTask(
[thread = network_thread_, worker_thread = worker_thread_.get()] {
thread->DisallowBlockingCalls();
thread->DisallowAllInvokes();
if (worker_thread == thread) { // In this case, worker_thread_ == network_thread_
thread->AllowInvokesToThread(thread);
}
});
}
SocketFactory* socket_factory = dependencies->socket_factory;
if (socket_factory == nullptr) {
if (owned_socket_factory_) {
socket_factory = owned_socket_factory_.get();
} else { // TODO(bugs.webrtc.org/13145): This case should be deleted. Either // require that a PacketSocketFactory and NetworkManager always are // injected (with no need to construct these default objects), or require // that if a network_thread is injected, an approprite // webrtc::SocketServer should be injected too.
socket_factory = network_thread()->socketserver();
}
}
if (!default_network_manager_) { // If network_monitor_factory_ is non-null, it will be used to create a // network monitor while on the network thread.
default_network_manager_ = std::make_unique<BasicNetworkManager>(
env, socket_factory, network_monitor_factory_.get());
}
if (!default_socket_factory_) {
default_socket_factory_ =
std::make_unique<BasicPacketSocketFactory>(socket_factory);
} // Set warning levels on the threads, to give warnings when response // may be slower than is expected of the thread. // Since some of the threads may be the same, start with the least // restrictive limits and end with the least permissive ones. // This will give warnings for all cases.
signaling_thread_->SetDispatchWarningMs(100);
worker_thread_->SetDispatchWarningMs(30);
network_thread_->SetDispatchWarningMs(10);
// Now that the `media_engine_reference_count_` will be 0 when we get here, // the blocking terminate operation that previously ran as part of the // destructor of the media engine, has already run and there's not // a need any longer to do the blocking call behind the // `blocking_media_engine_destruction_` flag.
RTC_DCHECK_EQ(media_engine_reference_count_, 0);
// `media_engine_` requires destruction to happen on the worker thread.
if (blocking_media_engine_destruction_) { // The media engine shares its Environment with objects that may outlive // the ConnectionContext if this call is not blocking. If Environment is // destroyed when ConnectionContext's destruction completes, this may // cause Use-After-Free. // // The plan is to address the problem with a new Terminate(callback) method, // which is referenced in webrtc:443588673, but pending this one can // control this with field trial `WebRTC-SynchronousDestructors`.
worker_thread_->BlockingCall([&] { media_engine_ = nullptr; });
} else {
worker_thread_->PostTask([media_engine = std::move(media_engine_)] {});
}
// Make sure `worker_thread()` and `signaling_thread()` outlive // `default_socket_factory_` and `default_network_manager_`.
default_socket_factory_ = nullptr;
default_network_manager_ = nullptr;
if (wraps_current_thread_)
ThreadManager::Instance()->UnwrapCurrentThread();
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.