blob: 6c6da4e476949376e7e00343db3fc0be16b93b50 [file] [log] [blame]
Harald Alvestranda39689c2020-10-15 08:34:311/*
2 * Copyright 2020 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include "pc/connection_context.h"
12
Harald Alvestrandffd5dc72020-10-20 15:35:3113#include <string>
14#include <type_traits>
Harald Alvestranda39689c2020-10-15 08:34:3115#include <utility>
16
17#include "api/transport/field_trial_based_config.h"
Florent Castelli6b0f19f2021-04-08 12:59:1218#include "media/sctp/sctp_transport_factory.h"
Harald Alvestrandffd5dc72020-10-20 15:35:3119#include "rtc_base/helpers.h"
Tomas Gunnarsson0b5ec182021-04-01 14:49:4220#include "rtc_base/task_utils/to_queued_task.h"
Harald Alvestrandffd5dc72020-10-20 15:35:3121#include "rtc_base/time_utils.h"
Harald Alvestranda39689c2020-10-15 08:34:3122
23namespace webrtc {
24
25namespace {
26
27rtc::Thread* MaybeStartThread(rtc::Thread* old_thread,
28 const std::string& thread_name,
29 bool with_socket_server,
Harald Alvestrand4244b5f2020-10-15 12:57:0530 std::unique_ptr<rtc::Thread>& thread_holder) {
Harald Alvestranda39689c2020-10-15 08:34:3131 if (old_thread) {
32 return old_thread;
33 }
34 if (with_socket_server) {
Harald Alvestrand4244b5f2020-10-15 12:57:0535 thread_holder = rtc::Thread::CreateWithSocketServer();
Harald Alvestranda39689c2020-10-15 08:34:3136 } else {
Harald Alvestrand4244b5f2020-10-15 12:57:0537 thread_holder = rtc::Thread::Create();
Harald Alvestranda39689c2020-10-15 08:34:3138 }
Harald Alvestrand4244b5f2020-10-15 12:57:0539 thread_holder->SetName(thread_name, nullptr);
40 thread_holder->Start();
41 return thread_holder.get();
Harald Alvestranda39689c2020-10-15 08:34:3142}
43
44rtc::Thread* MaybeWrapThread(rtc::Thread* signaling_thread,
Harald Alvestrand4244b5f2020-10-15 12:57:0545 bool& wraps_current_thread) {
46 wraps_current_thread = false;
Harald Alvestranda39689c2020-10-15 08:34:3147 if (signaling_thread) {
48 return signaling_thread;
49 }
50 auto this_thread = rtc::Thread::Current();
51 if (!this_thread) {
52 // If this thread isn't already wrapped by an rtc::Thread, create a
53 // wrapper and own it in this class.
54 this_thread = rtc::ThreadManager::Instance()->WrapCurrentThread();
Harald Alvestrand4244b5f2020-10-15 12:57:0555 wraps_current_thread = true;
Harald Alvestranda39689c2020-10-15 08:34:3156 }
57 return this_thread;
58}
59
Harald Alvestrand4244b5f2020-10-15 12:57:0560std::unique_ptr<SctpTransportFactoryInterface> MaybeCreateSctpFactory(
61 std::unique_ptr<SctpTransportFactoryInterface> factory,
62 rtc::Thread* network_thread) {
63 if (factory) {
64 return factory;
65 }
Mirko Bonadei5eb43b42021-01-18 12:24:4066#ifdef WEBRTC_HAVE_SCTP
Harald Alvestrand4244b5f2020-10-15 12:57:0567 return std::make_unique<cricket::SctpTransportFactory>(network_thread);
68#else
69 return nullptr;
70#endif
71}
72
Harald Alvestranda39689c2020-10-15 08:34:3173} // namespace
74
Harald Alvestrandffd5dc72020-10-20 15:35:3175// Static
76rtc::scoped_refptr<ConnectionContext> ConnectionContext::Create(
77 PeerConnectionFactoryDependencies* dependencies) {
Niels Möllere7cc8832022-01-04 14:20:0378 return rtc::scoped_refptr<ConnectionContext>(
79 new ConnectionContext(dependencies));
Harald Alvestrandffd5dc72020-10-20 15:35:3180}
81
Harald Alvestranda39689c2020-10-15 08:34:3182ConnectionContext::ConnectionContext(
Harald Alvestrandffd5dc72020-10-20 15:35:3183 PeerConnectionFactoryDependencies* dependencies)
84 : network_thread_(MaybeStartThread(dependencies->network_thread,
Harald Alvestranda39689c2020-10-15 08:34:3185 "pc_network_thread",
86 true,
Harald Alvestrand4244b5f2020-10-15 12:57:0587 owned_network_thread_)),
Harald Alvestrandffd5dc72020-10-20 15:35:3188 worker_thread_(MaybeStartThread(dependencies->worker_thread,
Harald Alvestranda39689c2020-10-15 08:34:3189 "pc_worker_thread",
90 false,
Harald Alvestrand4244b5f2020-10-15 12:57:0591 owned_worker_thread_)),
Harald Alvestrandffd5dc72020-10-20 15:35:3192 signaling_thread_(MaybeWrapThread(dependencies->signaling_thread,
Harald Alvestrand4244b5f2020-10-15 12:57:0593 wraps_current_thread_)),
Harald Alvestrandffd5dc72020-10-20 15:35:3194 network_monitor_factory_(
95 std::move(dependencies->network_monitor_factory)),
96 call_factory_(std::move(dependencies->call_factory)),
Harald Alvestrandffd5dc72020-10-20 15:35:3197 sctp_factory_(
98 MaybeCreateSctpFactory(std::move(dependencies->sctp_factory),
99 network_thread())),
100 trials_(dependencies->trials
101 ? std::move(dependencies->trials)
102 : std::make_unique<FieldTrialBasedConfig>()) {
Harald Alvestranda39689c2020-10-15 08:34:31103 signaling_thread_->AllowInvokesToThread(worker_thread_);
104 signaling_thread_->AllowInvokesToThread(network_thread_);
105 worker_thread_->AllowInvokesToThread(network_thread_);
Tomas Gunnarsson0b5ec182021-04-01 14:49:42106 if (network_thread_->IsCurrent()) {
Artem Titov15737162021-05-25 09:17:07107 // TODO(https://crbug.com/webrtc/12802) switch to DisallowAllInvokes
108 network_thread_->AllowInvokesToThread(network_thread_);
Tomas Gunnarsson0b5ec182021-04-01 14:49:42109 } else {
110 network_thread_->PostTask(ToQueuedTask([thread = network_thread_] {
111 thread->DisallowBlockingCalls();
Artem Titov15737162021-05-25 09:17:07112 // TODO(https://crbug.com/webrtc/12802) switch to DisallowAllInvokes
113 thread->AllowInvokesToThread(thread);
Tomas Gunnarsson0b5ec182021-04-01 14:49:42114 }));
115 }
Harald Alvestrandffd5dc72020-10-20 15:35:31116
117 RTC_DCHECK_RUN_ON(signaling_thread_);
118 rtc::InitRandom(rtc::Time32());
119
120 // If network_monitor_factory_ is non-null, it will be used to create a
121 // network monitor while on the network thread.
122 default_network_manager_ = std::make_unique<rtc::BasicNetworkManager>(
Niels Mölleraa373162021-09-28 14:09:07123 network_monitor_factory_.get(), network_thread()->socketserver());
Harald Alvestrandffd5dc72020-10-20 15:35:31124
Niels Möller9def9942021-09-07 07:16:49125 // TODO(bugs.webrtc.org/13145): Either require that a PacketSocketFactory
126 // always is injected (with no need to construct this default factory), or get
127 // the appropriate underlying SocketFactory without going through the
128 // rtc::Thread::socketserver() accessor.
129 default_socket_factory_ = std::make_unique<rtc::BasicPacketSocketFactory>(
130 network_thread()->socketserver());
Harald Alvestrandffd5dc72020-10-20 15:35:31131
Tomas Gunnarsson0b5ec182021-04-01 14:49:42132 worker_thread_->Invoke<void>(RTC_FROM_HERE, [&]() {
133 channel_manager_ = cricket::ChannelManager::Create(
134 std::move(dependencies->media_engine),
Harald Alvestrand7af57c62021-04-16 11:12:14135 /*enable_rtx=*/true, worker_thread(), network_thread());
Tomas Gunnarsson0b5ec182021-04-01 14:49:42136 });
Harald Alvestrandffd5dc72020-10-20 15:35:31137
Harald Alvestrandba694422021-01-27 21:52:14138 // Set warning levels on the threads, to give warnings when response
139 // may be slower than is expected of the thread.
140 // Since some of the threads may be the same, start with the least
141 // restrictive limits and end with the least permissive ones.
142 // This will give warnings for all cases.
143 signaling_thread_->SetDispatchWarningMs(100);
144 worker_thread_->SetDispatchWarningMs(30);
145 network_thread_->SetDispatchWarningMs(10);
Harald Alvestranda39689c2020-10-15 08:34:31146}
147
148ConnectionContext::~ConnectionContext() {
Harald Alvestrand4244b5f2020-10-15 12:57:05149 RTC_DCHECK_RUN_ON(signaling_thread_);
Tomas Gunnarsson0b5ec182021-04-01 14:49:42150 worker_thread_->Invoke<void>(RTC_FROM_HERE,
151 [&]() { channel_manager_.reset(nullptr); });
Harald Alvestranda39689c2020-10-15 08:34:31152
Artem Titov880fa812021-07-30 20:30:23153 // Make sure `worker_thread()` and `signaling_thread()` outlive
154 // `default_socket_factory_` and `default_network_manager_`.
Harald Alvestranda39689c2020-10-15 08:34:31155 default_socket_factory_ = nullptr;
156 default_network_manager_ = nullptr;
157
158 if (wraps_current_thread_)
159 rtc::ThreadManager::Instance()->UnwrapCurrentThread();
160}
161
Harald Alvestranda39689c2020-10-15 08:34:31162cricket::ChannelManager* ConnectionContext::channel_manager() const {
163 return channel_manager_.get();
164}
165
166} // namespace webrtc