Harald Alvestrand | a39689c | 2020-10-15 08:34:31 | [diff] [blame] | 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 | |
Harald Alvestrand | ffd5dc7 | 2020-10-20 15:35:31 | [diff] [blame] | 13 | #include <string> |
| 14 | #include <type_traits> |
Harald Alvestrand | a39689c | 2020-10-15 08:34:31 | [diff] [blame] | 15 | #include <utility> |
| 16 | |
| 17 | #include "api/transport/field_trial_based_config.h" |
Florent Castelli | 6b0f19f | 2021-04-08 12:59:12 | [diff] [blame] | 18 | #include "media/sctp/sctp_transport_factory.h" |
Harald Alvestrand | ffd5dc7 | 2020-10-20 15:35:31 | [diff] [blame] | 19 | #include "rtc_base/helpers.h" |
Tomas Gunnarsson | 0b5ec18 | 2021-04-01 14:49:42 | [diff] [blame] | 20 | #include "rtc_base/task_utils/to_queued_task.h" |
Harald Alvestrand | ffd5dc7 | 2020-10-20 15:35:31 | [diff] [blame] | 21 | #include "rtc_base/time_utils.h" |
Harald Alvestrand | a39689c | 2020-10-15 08:34:31 | [diff] [blame] | 22 | |
| 23 | namespace webrtc { |
| 24 | |
| 25 | namespace { |
| 26 | |
| 27 | rtc::Thread* MaybeStartThread(rtc::Thread* old_thread, |
| 28 | const std::string& thread_name, |
| 29 | bool with_socket_server, |
Harald Alvestrand | 4244b5f | 2020-10-15 12:57:05 | [diff] [blame] | 30 | std::unique_ptr<rtc::Thread>& thread_holder) { |
Harald Alvestrand | a39689c | 2020-10-15 08:34:31 | [diff] [blame] | 31 | if (old_thread) { |
| 32 | return old_thread; |
| 33 | } |
| 34 | if (with_socket_server) { |
Harald Alvestrand | 4244b5f | 2020-10-15 12:57:05 | [diff] [blame] | 35 | thread_holder = rtc::Thread::CreateWithSocketServer(); |
Harald Alvestrand | a39689c | 2020-10-15 08:34:31 | [diff] [blame] | 36 | } else { |
Harald Alvestrand | 4244b5f | 2020-10-15 12:57:05 | [diff] [blame] | 37 | thread_holder = rtc::Thread::Create(); |
Harald Alvestrand | a39689c | 2020-10-15 08:34:31 | [diff] [blame] | 38 | } |
Harald Alvestrand | 4244b5f | 2020-10-15 12:57:05 | [diff] [blame] | 39 | thread_holder->SetName(thread_name, nullptr); |
| 40 | thread_holder->Start(); |
| 41 | return thread_holder.get(); |
Harald Alvestrand | a39689c | 2020-10-15 08:34:31 | [diff] [blame] | 42 | } |
| 43 | |
| 44 | rtc::Thread* MaybeWrapThread(rtc::Thread* signaling_thread, |
Harald Alvestrand | 4244b5f | 2020-10-15 12:57:05 | [diff] [blame] | 45 | bool& wraps_current_thread) { |
| 46 | wraps_current_thread = false; |
Harald Alvestrand | a39689c | 2020-10-15 08:34:31 | [diff] [blame] | 47 | 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 Alvestrand | 4244b5f | 2020-10-15 12:57:05 | [diff] [blame] | 55 | wraps_current_thread = true; |
Harald Alvestrand | a39689c | 2020-10-15 08:34:31 | [diff] [blame] | 56 | } |
| 57 | return this_thread; |
| 58 | } |
| 59 | |
Harald Alvestrand | 4244b5f | 2020-10-15 12:57:05 | [diff] [blame] | 60 | std::unique_ptr<SctpTransportFactoryInterface> MaybeCreateSctpFactory( |
| 61 | std::unique_ptr<SctpTransportFactoryInterface> factory, |
| 62 | rtc::Thread* network_thread) { |
| 63 | if (factory) { |
| 64 | return factory; |
| 65 | } |
Mirko Bonadei | 5eb43b4 | 2021-01-18 12:24:40 | [diff] [blame] | 66 | #ifdef WEBRTC_HAVE_SCTP |
Harald Alvestrand | 4244b5f | 2020-10-15 12:57:05 | [diff] [blame] | 67 | return std::make_unique<cricket::SctpTransportFactory>(network_thread); |
| 68 | #else |
| 69 | return nullptr; |
| 70 | #endif |
| 71 | } |
| 72 | |
Harald Alvestrand | a39689c | 2020-10-15 08:34:31 | [diff] [blame] | 73 | } // namespace |
| 74 | |
Harald Alvestrand | ffd5dc7 | 2020-10-20 15:35:31 | [diff] [blame] | 75 | // Static |
| 76 | rtc::scoped_refptr<ConnectionContext> ConnectionContext::Create( |
| 77 | PeerConnectionFactoryDependencies* dependencies) { |
Niels Möller | e7cc883 | 2022-01-04 14:20:03 | [diff] [blame] | 78 | return rtc::scoped_refptr<ConnectionContext>( |
| 79 | new ConnectionContext(dependencies)); |
Harald Alvestrand | ffd5dc7 | 2020-10-20 15:35:31 | [diff] [blame] | 80 | } |
| 81 | |
Harald Alvestrand | a39689c | 2020-10-15 08:34:31 | [diff] [blame] | 82 | ConnectionContext::ConnectionContext( |
Harald Alvestrand | ffd5dc7 | 2020-10-20 15:35:31 | [diff] [blame] | 83 | PeerConnectionFactoryDependencies* dependencies) |
| 84 | : network_thread_(MaybeStartThread(dependencies->network_thread, |
Harald Alvestrand | a39689c | 2020-10-15 08:34:31 | [diff] [blame] | 85 | "pc_network_thread", |
| 86 | true, |
Harald Alvestrand | 4244b5f | 2020-10-15 12:57:05 | [diff] [blame] | 87 | owned_network_thread_)), |
Harald Alvestrand | ffd5dc7 | 2020-10-20 15:35:31 | [diff] [blame] | 88 | worker_thread_(MaybeStartThread(dependencies->worker_thread, |
Harald Alvestrand | a39689c | 2020-10-15 08:34:31 | [diff] [blame] | 89 | "pc_worker_thread", |
| 90 | false, |
Harald Alvestrand | 4244b5f | 2020-10-15 12:57:05 | [diff] [blame] | 91 | owned_worker_thread_)), |
Harald Alvestrand | ffd5dc7 | 2020-10-20 15:35:31 | [diff] [blame] | 92 | signaling_thread_(MaybeWrapThread(dependencies->signaling_thread, |
Harald Alvestrand | 4244b5f | 2020-10-15 12:57:05 | [diff] [blame] | 93 | wraps_current_thread_)), |
Harald Alvestrand | ffd5dc7 | 2020-10-20 15:35:31 | [diff] [blame] | 94 | network_monitor_factory_( |
| 95 | std::move(dependencies->network_monitor_factory)), |
| 96 | call_factory_(std::move(dependencies->call_factory)), |
Harald Alvestrand | ffd5dc7 | 2020-10-20 15:35:31 | [diff] [blame] | 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>()) { |
Harald Alvestrand | a39689c | 2020-10-15 08:34:31 | [diff] [blame] | 103 | signaling_thread_->AllowInvokesToThread(worker_thread_); |
| 104 | signaling_thread_->AllowInvokesToThread(network_thread_); |
| 105 | worker_thread_->AllowInvokesToThread(network_thread_); |
Tomas Gunnarsson | 0b5ec18 | 2021-04-01 14:49:42 | [diff] [blame] | 106 | if (network_thread_->IsCurrent()) { |
Artem Titov | 1573716 | 2021-05-25 09:17:07 | [diff] [blame] | 107 | // TODO(https://crbug.com/webrtc/12802) switch to DisallowAllInvokes |
| 108 | network_thread_->AllowInvokesToThread(network_thread_); |
Tomas Gunnarsson | 0b5ec18 | 2021-04-01 14:49:42 | [diff] [blame] | 109 | } else { |
| 110 | network_thread_->PostTask(ToQueuedTask([thread = network_thread_] { |
| 111 | thread->DisallowBlockingCalls(); |
Artem Titov | 1573716 | 2021-05-25 09:17:07 | [diff] [blame] | 112 | // TODO(https://crbug.com/webrtc/12802) switch to DisallowAllInvokes |
| 113 | thread->AllowInvokesToThread(thread); |
Tomas Gunnarsson | 0b5ec18 | 2021-04-01 14:49:42 | [diff] [blame] | 114 | })); |
| 115 | } |
Harald Alvestrand | ffd5dc7 | 2020-10-20 15:35:31 | [diff] [blame] | 116 | |
| 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öller | aa37316 | 2021-09-28 14:09:07 | [diff] [blame] | 123 | network_monitor_factory_.get(), network_thread()->socketserver()); |
Harald Alvestrand | ffd5dc7 | 2020-10-20 15:35:31 | [diff] [blame] | 124 | |
Niels Möller | 9def994 | 2021-09-07 07:16:49 | [diff] [blame] | 125 | // 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 Alvestrand | ffd5dc7 | 2020-10-20 15:35:31 | [diff] [blame] | 131 | |
Tomas Gunnarsson | 0b5ec18 | 2021-04-01 14:49:42 | [diff] [blame] | 132 | worker_thread_->Invoke<void>(RTC_FROM_HERE, [&]() { |
| 133 | channel_manager_ = cricket::ChannelManager::Create( |
| 134 | std::move(dependencies->media_engine), |
Harald Alvestrand | 7af57c6 | 2021-04-16 11:12:14 | [diff] [blame] | 135 | /*enable_rtx=*/true, worker_thread(), network_thread()); |
Tomas Gunnarsson | 0b5ec18 | 2021-04-01 14:49:42 | [diff] [blame] | 136 | }); |
Harald Alvestrand | ffd5dc7 | 2020-10-20 15:35:31 | [diff] [blame] | 137 | |
Harald Alvestrand | ba69442 | 2021-01-27 21:52:14 | [diff] [blame] | 138 | // 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 Alvestrand | a39689c | 2020-10-15 08:34:31 | [diff] [blame] | 146 | } |
| 147 | |
| 148 | ConnectionContext::~ConnectionContext() { |
Harald Alvestrand | 4244b5f | 2020-10-15 12:57:05 | [diff] [blame] | 149 | RTC_DCHECK_RUN_ON(signaling_thread_); |
Tomas Gunnarsson | 0b5ec18 | 2021-04-01 14:49:42 | [diff] [blame] | 150 | worker_thread_->Invoke<void>(RTC_FROM_HERE, |
| 151 | [&]() { channel_manager_.reset(nullptr); }); |
Harald Alvestrand | a39689c | 2020-10-15 08:34:31 | [diff] [blame] | 152 | |
Artem Titov | 880fa81 | 2021-07-30 20:30:23 | [diff] [blame] | 153 | // Make sure `worker_thread()` and `signaling_thread()` outlive |
| 154 | // `default_socket_factory_` and `default_network_manager_`. |
Harald Alvestrand | a39689c | 2020-10-15 08:34:31 | [diff] [blame] | 155 | default_socket_factory_ = nullptr; |
| 156 | default_network_manager_ = nullptr; |
| 157 | |
| 158 | if (wraps_current_thread_) |
| 159 | rtc::ThreadManager::Instance()->UnwrapCurrentThread(); |
| 160 | } |
| 161 | |
Harald Alvestrand | a39689c | 2020-10-15 08:34:31 | [diff] [blame] | 162 | cricket::ChannelManager* ConnectionContext::channel_manager() const { |
| 163 | return channel_manager_.get(); |
| 164 | } |
| 165 | |
| 166 | } // namespace webrtc |