1 /*
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
13 #include <string>
14 #include <type_traits>
15 #include <utility>
16
17 #include "api/transport/field_trial_based_config.h"
18 #include "media/base/rtp_data_engine.h"
19 #include "rtc_base/helpers.h"
20 #include "rtc_base/ref_counted_object.h"
21 #include "rtc_base/task_utils/to_queued_task.h"
22 #include "rtc_base/time_utils.h"
23
24 namespace webrtc {
25
26 namespace {
27
MaybeStartThread(rtc::Thread * old_thread,const std::string & thread_name,bool with_socket_server,std::unique_ptr<rtc::Thread> & thread_holder)28 rtc::Thread* MaybeStartThread(rtc::Thread* old_thread,
29 const std::string& thread_name,
30 bool with_socket_server,
31 std::unique_ptr<rtc::Thread>& thread_holder) {
32 if (old_thread) {
33 return old_thread;
34 }
35 if (with_socket_server) {
36 thread_holder = rtc::Thread::CreateWithSocketServer();
37 } else {
38 thread_holder = rtc::Thread::Create();
39 }
40 thread_holder->SetName(thread_name, nullptr);
41 thread_holder->Start();
42 return thread_holder.get();
43 }
44
MaybeWrapThread(rtc::Thread * signaling_thread,bool & wraps_current_thread)45 rtc::Thread* MaybeWrapThread(rtc::Thread* signaling_thread,
46 bool& wraps_current_thread) {
47 wraps_current_thread = false;
48 if (signaling_thread) {
49 return signaling_thread;
50 }
51 auto this_thread = rtc::Thread::Current();
52 if (!this_thread) {
53 // If this thread isn't already wrapped by an rtc::Thread, create a
54 // wrapper and own it in this class.
55 this_thread = rtc::ThreadManager::Instance()->WrapCurrentThread();
56 wraps_current_thread = true;
57 }
58 return this_thread;
59 }
60
MaybeCreateSctpFactory(std::unique_ptr<SctpTransportFactoryInterface> factory,rtc::Thread * network_thread)61 std::unique_ptr<SctpTransportFactoryInterface> MaybeCreateSctpFactory(
62 std::unique_ptr<SctpTransportFactoryInterface> factory,
63 rtc::Thread* network_thread) {
64 if (factory) {
65 return factory;
66 }
67 #ifdef WEBRTC_HAVE_SCTP
68 return std::make_unique<cricket::SctpTransportFactory>(network_thread);
69 #else
70 return nullptr;
71 #endif
72 }
73
74 } // namespace
75
76 // Static
Create(PeerConnectionFactoryDependencies * dependencies)77 rtc::scoped_refptr<ConnectionContext> ConnectionContext::Create(
78 PeerConnectionFactoryDependencies* dependencies) {
79 return new rtc::RefCountedObject<ConnectionContext>(dependencies);
80 }
81
ConnectionContext(PeerConnectionFactoryDependencies * dependencies)82 ConnectionContext::ConnectionContext(
83 PeerConnectionFactoryDependencies* dependencies)
84 : network_thread_(MaybeStartThread(dependencies->network_thread,
85 "pc_network_thread",
86 true,
87 owned_network_thread_)),
88 worker_thread_(MaybeStartThread(dependencies->worker_thread,
89 "pc_worker_thread",
90 false,
91 owned_worker_thread_)),
92 signaling_thread_(MaybeWrapThread(dependencies->signaling_thread,
93 wraps_current_thread_)),
94 network_monitor_factory_(
95 std::move(dependencies->network_monitor_factory)),
96 call_factory_(std::move(dependencies->call_factory)),
97 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>()) {
103 signaling_thread_->AllowInvokesToThread(worker_thread_);
104 signaling_thread_->AllowInvokesToThread(network_thread_);
105 worker_thread_->AllowInvokesToThread(network_thread_);
106 if (network_thread_->IsCurrent()) {
107 network_thread_->DisallowAllInvokes();
108 } else {
109 network_thread_->PostTask(ToQueuedTask([thread = network_thread_] {
110 thread->DisallowBlockingCalls();
111 thread->DisallowAllInvokes();
112 }));
113 }
114
115 RTC_DCHECK_RUN_ON(signaling_thread_);
116 rtc::InitRandom(rtc::Time32());
117
118 // If network_monitor_factory_ is non-null, it will be used to create a
119 // network monitor while on the network thread.
120 default_network_manager_ = std::make_unique<rtc::BasicNetworkManager>(
121 network_monitor_factory_.get());
122
123 default_socket_factory_ =
124 std::make_unique<rtc::BasicPacketSocketFactory>(network_thread());
125
126 worker_thread_->Invoke<void>(RTC_FROM_HERE, [&]() {
127 channel_manager_ = cricket::ChannelManager::Create(
128 std::move(dependencies->media_engine),
129 std::make_unique<cricket::RtpDataEngine>(), /*enable_rtx=*/true,
130 worker_thread(), network_thread());
131 });
132
133 // Set warning levels on the threads, to give warnings when response
134 // may be slower than is expected of the thread.
135 // Since some of the threads may be the same, start with the least
136 // restrictive limits and end with the least permissive ones.
137 // This will give warnings for all cases.
138 signaling_thread_->SetDispatchWarningMs(100);
139 worker_thread_->SetDispatchWarningMs(30);
140 network_thread_->SetDispatchWarningMs(10);
141 }
142
~ConnectionContext()143 ConnectionContext::~ConnectionContext() {
144 RTC_DCHECK_RUN_ON(signaling_thread_);
145 worker_thread_->Invoke<void>(RTC_FROM_HERE,
146 [&]() { channel_manager_.reset(nullptr); });
147
148 // Make sure |worker_thread()| and |signaling_thread()| outlive
149 // |default_socket_factory_| and |default_network_manager_|.
150 default_socket_factory_ = nullptr;
151 default_network_manager_ = nullptr;
152
153 if (wraps_current_thread_)
154 rtc::ThreadManager::Instance()->UnwrapCurrentThread();
155 }
156
channel_manager() const157 cricket::ChannelManager* ConnectionContext::channel_manager() const {
158 return channel_manager_.get();
159 }
160
161 } // namespace webrtc
162