diff options
Diffstat (limited to 'third_party/libwebrtc/pc/connection_context.cc')
-rw-r--r-- | third_party/libwebrtc/pc/connection_context.cc | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/third_party/libwebrtc/pc/connection_context.cc b/third_party/libwebrtc/pc/connection_context.cc new file mode 100644 index 0000000000..d048218cb9 --- /dev/null +++ b/third_party/libwebrtc/pc/connection_context.cc @@ -0,0 +1,188 @@ +/* + * Copyright 2020 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "pc/connection_context.h" + +#include <type_traits> +#include <utility> +#include <vector> + +#include "api/transport/field_trial_based_config.h" +#include "media/base/media_engine.h" +#include "media/sctp/sctp_transport_factory.h" +#include "rtc_base/helpers.h" +#include "rtc_base/internal/default_socket_server.h" +#include "rtc_base/socket_server.h" +#include "rtc_base/time_utils.h" + +namespace webrtc { + +namespace { + +rtc::Thread* MaybeStartNetworkThread( + rtc::Thread* old_thread, + std::unique_ptr<rtc::SocketFactory>& socket_factory_holder, + std::unique_ptr<rtc::Thread>& thread_holder) { + if (old_thread) { + return old_thread; + } + std::unique_ptr<rtc::SocketServer> socket_server = + rtc::CreateDefaultSocketServer(); + thread_holder = std::make_unique<rtc::Thread>(socket_server.get()); + socket_factory_holder = std::move(socket_server); + + thread_holder->SetName("pc_network_thread", nullptr); + thread_holder->Start(); + return thread_holder.get(); +} + +rtc::Thread* MaybeWrapThread(rtc::Thread* signaling_thread, + bool& wraps_current_thread) { + wraps_current_thread = false; + if (signaling_thread) { + return signaling_thread; + } + auto this_thread = rtc::Thread::Current(); + if (!this_thread) { + // If this thread isn't already wrapped by an rtc::Thread, create a + // wrapper and own it in this class. + this_thread = rtc::ThreadManager::Instance()->WrapCurrentThread(); + wraps_current_thread = true; + } + return this_thread; +} + +std::unique_ptr<SctpTransportFactoryInterface> MaybeCreateSctpFactory( + std::unique_ptr<SctpTransportFactoryInterface> factory, + rtc::Thread* network_thread, + const FieldTrialsView& field_trials) { + if (factory) { + return factory; + } +#ifdef WEBRTC_HAVE_SCTP + return std::make_unique<cricket::SctpTransportFactory>(network_thread); +#else + return nullptr; +#endif +} + +} // namespace + +// Static +rtc::scoped_refptr<ConnectionContext> ConnectionContext::Create( + PeerConnectionFactoryDependencies* dependencies) { + return rtc::scoped_refptr<ConnectionContext>( + new ConnectionContext(dependencies)); +} + +ConnectionContext::ConnectionContext( + PeerConnectionFactoryDependencies* dependencies) + : network_thread_(MaybeStartNetworkThread(dependencies->network_thread, + owned_socket_factory_, + owned_network_thread_)), + worker_thread_(dependencies->worker_thread, + []() { + auto thread_holder = rtc::Thread::Create(); + thread_holder->SetName("pc_worker_thread", nullptr); + thread_holder->Start(); + return thread_holder; + }), + signaling_thread_(MaybeWrapThread(dependencies->signaling_thread, + wraps_current_thread_)), + trials_(dependencies->trials ? std::move(dependencies->trials) + : std::make_unique<FieldTrialBasedConfig>()), + media_engine_(std::move(dependencies->media_engine)), + network_monitor_factory_( + std::move(dependencies->network_monitor_factory)), + default_network_manager_(std::move(dependencies->network_manager)), + call_factory_(std::move(dependencies->call_factory)), + default_socket_factory_(std::move(dependencies->packet_socket_factory)), + sctp_factory_( + MaybeCreateSctpFactory(std::move(dependencies->sctp_factory), + network_thread(), + *trials_.get())) { + RTC_DCHECK_RUN_ON(signaling_thread_); + RTC_DCHECK(!(default_network_manager_ && network_monitor_factory_)) + << "You can't set both network_manager and network_monitor_factory."; + + 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); + } + }); + } + + rtc::InitRandom(rtc::Time32()); + + rtc::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 rtc::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<rtc::BasicNetworkManager>( + network_monitor_factory_.get(), socket_factory, &field_trials()); + } + if (!default_socket_factory_) { + default_socket_factory_ = + std::make_unique<rtc::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); + + if (media_engine_) { + // TODO(tommi): Change VoiceEngine to do ctor time initialization so that + // this isn't necessary. + worker_thread_->BlockingCall([&] { media_engine_->Init(); }); + } +} + +ConnectionContext::~ConnectionContext() { + RTC_DCHECK_RUN_ON(signaling_thread_); + // `media_engine_` requires destruction to happen on the worker thread. + 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_) + rtc::ThreadManager::Instance()->UnwrapCurrentThread(); +} + +} // namespace webrtc |