Chromium Code Reviews| Index: net/quic/quartc/quartc_factory.cc |
| diff --git a/net/quic/quartc/quartc_factory.cc b/net/quic/quartc/quartc_factory.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..20531bef973879ae7c52fd6f6ad8aed889722306 |
| --- /dev/null |
| +++ b/net/quic/quartc/quartc_factory.cc |
| @@ -0,0 +1,161 @@ |
| +// Copyright (c) 2016 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "net/quic/quartc/quartc_factory.h" |
| + |
| +#include "net/quic/core/crypto/quic_random.h" |
| +#include "net/quic/quartc/quartc_alarm_factory.h" |
| +#include "net/quic/quartc/quartc_session.h" |
| + |
| +namespace { |
| + |
| +// Implements the QuicAlarm with QuartcTaskRunnerInterface for the Quartc |
| +// users other than Chromium. For example, WebRTC will create QuartcAlarm with |
| +// a QuartcTaskRunner implemented by WebRTC. |
| +class QuartcAlarm : public net::QuicAlarm, |
| + public net::QuartcTaskRunnerInterface::Task { |
| + public: |
| + QuartcAlarm(const net::QuicClock* clock, |
| + net::QuartcTaskRunnerInterface* task_runner, |
| + net::QuicArenaScopedPtr<QuicAlarm::Delegate> delegate) |
| + : net::QuicAlarm(std::move(delegate)), |
| + clock_(clock), |
| + task_runner_(task_runner) {} |
| + |
| + // QuicAlarm overrides. |
| + void SetImpl() override { |
| + DCHECK(deadline().IsInitialized()); |
| + // Cancel it if already set. |
| + CancelImpl(); |
| + |
| + int64_t delay_ms = (deadline() - (clock_->Now())).ToMilliseconds(); |
| + if (delay_ms < 0) { |
| + delay_ms = 0; |
| + } |
| + |
| + DCHECK(task_runner_); |
| + DCHECK(!scheduled_task_); |
| + scheduled_task_.reset((task_runner_->Schedule(this, delay_ms)).release()); |
| + } |
| + |
| + void CancelImpl() override { |
| + if (scheduled_task_) { |
| + scheduled_task_->Cancel(); |
| + scheduled_task_.reset(); |
| + } |
| + } |
| + |
| + // QuartcTaskRunner::Task overrides. |
| + void Run() override { |
| + // The alarm may have been cancelled. |
| + if (!deadline().IsInitialized()) { |
| + return; |
| + } |
| + |
| + // The alarm may have been re-set to a later time. |
| + if (clock_->Now() < deadline()) { |
| + SetImpl(); |
| + return; |
| + } |
| + |
| + Fire(); |
| + } |
| + |
| + private: |
| + // Not owned by QuartcAlarm. Owned by the QuartcFactory. |
| + const net::QuicClock* clock_; |
| + // Not owned by QuartcAlarm. Owned by the QuartcFactory. |
| + net::QuartcTaskRunnerInterface* task_runner_; |
| + // Owned by QuartcAlarm. |
| + std::unique_ptr<net::QuartcTaskRunnerInterface::ScheduledTask> |
| + scheduled_task_; |
| +}; |
| + |
| +} // namespace |
| + |
| +namespace net { |
| + |
| +// Only one AtExitManager is expected to be created for one process. |
| +static base::AtExitManager* at_exit_manager = nullptr; |
| + |
| +QuartcFactory::QuartcFactory(const QuartcFactoryConfig& factory_config) { |
| + task_runner_.reset(factory_config.task_runner); |
| + if (!at_exit_manager) { |
|
pthatcher1
2016/10/16 01:15:27
I think a simpler solution would be to just have a
zhihuang1
2016/10/16 19:38:12
Yes, I agree. We don't have much control on the At
pthatcher2
2016/10/24 17:42:49
It depends on how we use QuicTransportChannels. I
|
| + LOG(WARNING) << "The AtExitManager has already been created."; |
| + return; |
| + } |
| + at_exit_manager = new base::AtExitManager; |
|
pthatcher1
2016/10/16 01:15:27
What happened to the test one?
zhihuang1
2016/10/16 19:38:12
We need the test mode AtExitManager only in the un
|
| +} |
| + |
| +QuartcFactory::~QuartcFactory() { |
| + if (!at_exit_manager) { |
| + delete at_exit_manager; |
| + at_exit_manager = nullptr; |
| + } |
| +} |
| + |
| +std::unique_ptr<QuartcSessionInterface> QuartcFactory::CreateQuartcSession( |
| + const QuartcSessionConfig& quartc_session_config) { |
| + DCHECK(quartc_session_config.packet_transport); |
| + |
| + Perspective perspective = quartc_session_config.is_server |
| + ? Perspective::IS_SERVER |
| + : Perspective::IS_CLIENT; |
| + std::unique_ptr<QuicConnection> quic_connection = |
| + CreateQuicConnection(quartc_session_config, perspective); |
| + QuicConfig quic_config; |
| + return std::unique_ptr<QuartcSessionInterface>( |
| + new QuartcSession(std::move(quic_connection), quic_config, |
| + quartc_session_config.unique_remote_server_id, |
| + perspective, this /*QuicConnectionHelperInterface*/)); |
| +} |
| + |
| +std::unique_ptr<QuicConnection> QuartcFactory::CreateQuicConnection( |
| + const QuartcSessionConfig& quartc_session_config, |
| + Perspective perspective) { |
| + // The QuicConnection will take the ownership. |
| + std::unique_ptr<QuartcPacketWriter> writer( |
| + new QuartcPacketWriter(quartc_session_config.packet_transport, |
| + quartc_session_config.max_packet_size)); |
| + // dummy_id and dummy_address are used because Quartc network layer will not |
| + // use these two. |
| + QuicConnectionId dummy_id = 0; |
| + IPEndPoint dummy_address(IPAddress(0, 0, 0, 0), 0 /*Port*/); |
| + return std::unique_ptr<QuicConnection>(new QuicConnection( |
| + dummy_id, dummy_address, this, /*QuicConnectionHelperInterface*/ |
| + this /*QuicAlarmFactory*/, writer.release(), true /*own the writer*/, |
| + perspective, AllSupportedVersions())); |
| +} |
| + |
| +QuicAlarm* QuartcFactory::CreateAlarm(QuicAlarm::Delegate* delegate) { |
| + return new QuartcAlarm(GetClock(), task_runner_.get(), |
| + QuicArenaScopedPtr<QuicAlarm::Delegate>(delegate)); |
| +} |
| + |
| +QuicArenaScopedPtr<QuicAlarm> QuartcFactory::CreateAlarm( |
| + QuicArenaScopedPtr<QuicAlarm::Delegate> delegate, |
| + QuicConnectionArena* arena) { |
| + return QuicArenaScopedPtr<QuicAlarm>( |
| + new QuartcAlarm(GetClock(), task_runner_.get(), std::move(delegate))); |
| +} |
| + |
| +const QuicClock* QuartcFactory::GetClock() const { |
| + return &clock_; |
| +} |
| + |
| +QuicRandom* QuartcFactory::GetRandomGenerator() { |
| + return QuicRandom::GetInstance(); |
| +} |
| + |
| +QuicBufferAllocator* QuartcFactory::GetBufferAllocator() { |
| + return &buffer_allocator_; |
| +} |
| + |
| +std::unique_ptr<QuartcFactoryInterface> CreateQuartcFactory( |
| + const QuartcFactoryConfig& factory_config) { |
| + return std::unique_ptr<QuartcFactoryInterface>( |
| + new QuartcFactory(factory_config)); |
| +} |
| + |
| +} // namespace net |