/* * Copyright 2017 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 "webrtc/api/ortcfactory.h" #include #include // For std::move. #include "webrtc/base/bind.h" #include "webrtc/base/asyncpacketsocket.h" #include "webrtc/p2p/base/basicpacketsocketfactory.h" #include "webrtc/p2p/base/udptransport.h" namespace webrtc { // static std::unique_ptr OrtcFactoryInterface::Create( rtc::Thread* network_thread, rtc::Thread* signaling_thread, rtc::NetworkManager* network_manager, rtc::PacketSocketFactory* socket_factory) { // Hop to signaling thread if needed. if (signaling_thread && !signaling_thread->IsCurrent()) { return signaling_thread->Invoke>( RTC_FROM_HERE, rtc::Bind(&OrtcFactoryInterface::Create, network_thread, signaling_thread, network_manager, socket_factory)); } OrtcFactory* new_factory = new OrtcFactory(network_thread, signaling_thread, network_manager, socket_factory); // Return a proxy so that any calls on the returned object (including // destructor) happen on the signaling thread. return OrtcFactoryProxy::Create(new_factory->signaling_thread(), new_factory->network_thread(), new_factory); } OrtcFactory::OrtcFactory(rtc::Thread* network_thread, rtc::Thread* signaling_thread, rtc::NetworkManager* network_manager, rtc::PacketSocketFactory* socket_factory) : network_thread_(network_thread), signaling_thread_(signaling_thread), network_manager_(network_manager), socket_factory_(socket_factory) { if (!network_thread_) { owned_network_thread_ = rtc::Thread::CreateWithSocketServer(); owned_network_thread_->Start(); network_thread_ = owned_network_thread_.get(); } // The worker thread is created internally because it's an implementation // detail, and consumers of the API don't need to really know about it. owned_worker_thread_ = rtc::Thread::Create(); owned_worker_thread_->Start(); if (signaling_thread_) { RTC_DCHECK_RUN_ON(signaling_thread_); } else { signaling_thread_ = rtc::Thread::Current(); if (!signaling_thread_) { // If this thread isn't already wrapped by an rtc::Thread, create a // wrapper and own it in this class. signaling_thread_ = rtc::ThreadManager::Instance()->WrapCurrentThread(); wraps_signaling_thread_ = true; } } if (!network_manager_) { owned_network_manager_.reset(new rtc::BasicNetworkManager()); network_manager_ = owned_network_manager_.get(); } if (!socket_factory_) { owned_socket_factory_.reset( new rtc::BasicPacketSocketFactory(network_thread_)); socket_factory_ = owned_socket_factory_.get(); } } OrtcFactory::~OrtcFactory() { RTC_DCHECK_RUN_ON(signaling_thread_); if (wraps_signaling_thread_) { rtc::ThreadManager::Instance()->UnwrapCurrentThread(); } } std::unique_ptr OrtcFactory::CreateUdpTransport( int family, uint16_t min_port, uint16_t max_port) { if (!network_thread_->IsCurrent()) { RTC_DCHECK_RUN_ON(signaling_thread_); return network_thread_->Invoke>( RTC_FROM_HERE, rtc::Bind(&OrtcFactory::CreateUdpTransport, this, family, min_port, max_port)); } std::unique_ptr socket( socket_factory_->CreateUdpSocket( rtc::SocketAddress(rtc::GetAnyIP(family), 0), min_port, max_port)); if (!socket) { LOG(LS_WARNING) << "Local socket allocation failure."; return nullptr; } LOG(LS_INFO) << "Created UDP socket with address " << socket->GetLocalAddress().ToSensitiveString() << "."; // Use proxy so that calls to the returned object are invoked on the network // thread. return UdpTransportProxy::Create( signaling_thread_, network_thread_, new cricket::UdpTransport(std::string(), std::move(socket))); } } // namespace webrtc