2020-12-23 07:48:30 +00:00
|
|
|
/*
|
|
|
|
* 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 <string>
|
|
|
|
#include <type_traits>
|
|
|
|
#include <utility>
|
|
|
|
|
|
|
|
#include "api/transport/field_trial_based_config.h"
|
2021-06-25 00:43:10 +00:00
|
|
|
#include "media/sctp/sctp_transport_factory.h"
|
2020-12-23 07:48:30 +00:00
|
|
|
#include "rtc_base/helpers.h"
|
2021-06-25 00:43:10 +00:00
|
|
|
#include "rtc_base/task_utils/to_queued_task.h"
|
2020-12-23 07:48:30 +00:00
|
|
|
#include "rtc_base/time_utils.h"
|
|
|
|
|
|
|
|
namespace webrtc {
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
rtc::Thread* MaybeStartThread(rtc::Thread* old_thread,
|
|
|
|
const std::string& thread_name,
|
|
|
|
bool with_socket_server,
|
|
|
|
std::unique_ptr<rtc::Thread>& thread_holder) {
|
|
|
|
if (old_thread) {
|
|
|
|
return old_thread;
|
|
|
|
}
|
|
|
|
if (with_socket_server) {
|
|
|
|
thread_holder = rtc::Thread::CreateWithSocketServer();
|
|
|
|
} else {
|
|
|
|
thread_holder = rtc::Thread::Create();
|
|
|
|
}
|
|
|
|
thread_holder->SetName(thread_name, 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) {
|
|
|
|
if (factory) {
|
|
|
|
return factory;
|
|
|
|
}
|
2021-06-25 00:43:10 +00:00
|
|
|
#ifdef WEBRTC_HAVE_SCTP
|
2020-12-23 07:48:30 +00:00
|
|
|
return std::make_unique<cricket::SctpTransportFactory>(network_thread);
|
|
|
|
#else
|
|
|
|
return nullptr;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
// Static
|
|
|
|
rtc::scoped_refptr<ConnectionContext> ConnectionContext::Create(
|
|
|
|
PeerConnectionFactoryDependencies* dependencies) {
|
2021-06-25 00:43:10 +00:00
|
|
|
return new ConnectionContext(dependencies);
|
2020-12-23 07:48:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ConnectionContext::ConnectionContext(
|
|
|
|
PeerConnectionFactoryDependencies* dependencies)
|
|
|
|
: network_thread_(MaybeStartThread(dependencies->network_thread,
|
|
|
|
"pc_network_thread",
|
|
|
|
true,
|
|
|
|
owned_network_thread_)),
|
|
|
|
worker_thread_(MaybeStartThread(dependencies->worker_thread,
|
|
|
|
"pc_worker_thread",
|
|
|
|
false,
|
|
|
|
owned_worker_thread_)),
|
|
|
|
signaling_thread_(MaybeWrapThread(dependencies->signaling_thread,
|
|
|
|
wraps_current_thread_)),
|
|
|
|
network_monitor_factory_(
|
|
|
|
std::move(dependencies->network_monitor_factory)),
|
|
|
|
call_factory_(std::move(dependencies->call_factory)),
|
|
|
|
sctp_factory_(
|
|
|
|
MaybeCreateSctpFactory(std::move(dependencies->sctp_factory),
|
|
|
|
network_thread())),
|
|
|
|
trials_(dependencies->trials
|
|
|
|
? std::move(dependencies->trials)
|
|
|
|
: std::make_unique<FieldTrialBasedConfig>()) {
|
|
|
|
signaling_thread_->AllowInvokesToThread(worker_thread_);
|
|
|
|
signaling_thread_->AllowInvokesToThread(network_thread_);
|
|
|
|
worker_thread_->AllowInvokesToThread(network_thread_);
|
2021-06-25 00:43:10 +00:00
|
|
|
if (network_thread_->IsCurrent()) {
|
|
|
|
network_thread_->DisallowAllInvokes();
|
|
|
|
} else {
|
|
|
|
network_thread_->PostTask(ToQueuedTask([thread = network_thread_] {
|
|
|
|
thread->DisallowBlockingCalls();
|
|
|
|
thread->DisallowAllInvokes();
|
|
|
|
}));
|
|
|
|
}
|
2020-12-23 07:48:30 +00:00
|
|
|
|
|
|
|
RTC_DCHECK_RUN_ON(signaling_thread_);
|
|
|
|
rtc::InitRandom(rtc::Time32());
|
|
|
|
|
|
|
|
// 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());
|
|
|
|
|
|
|
|
default_socket_factory_ =
|
|
|
|
std::make_unique<rtc::BasicPacketSocketFactory>(network_thread());
|
|
|
|
|
2021-06-25 00:43:10 +00:00
|
|
|
worker_thread_->Invoke<void>(RTC_FROM_HERE, [&]() {
|
|
|
|
channel_manager_ = cricket::ChannelManager::Create(
|
|
|
|
std::move(dependencies->media_engine),
|
|
|
|
/*enable_rtx=*/true, worker_thread(), network_thread());
|
|
|
|
});
|
|
|
|
|
|
|
|
// 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);
|
2020-12-23 07:48:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ConnectionContext::~ConnectionContext() {
|
|
|
|
RTC_DCHECK_RUN_ON(signaling_thread_);
|
2021-06-25 00:43:10 +00:00
|
|
|
worker_thread_->Invoke<void>(RTC_FROM_HERE,
|
|
|
|
[&]() { channel_manager_.reset(nullptr); });
|
2020-12-23 07:48:30 +00:00
|
|
|
|
|
|
|
// 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();
|
|
|
|
}
|
|
|
|
|
|
|
|
cricket::ChannelManager* ConnectionContext::channel_manager() const {
|
|
|
|
return channel_manager_.get();
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace webrtc
|