Move QboneTunnelSilo to third_party. PiperOrigin-RevId: 344249287 Change-Id: I7dfea6bc00b03db049fdf3a3f4cc4bf18456e49d
diff --git a/quic/qbone/bonnet/qbone_tunnel_silo.cc b/quic/qbone/bonnet/qbone_tunnel_silo.cc new file mode 100644 index 0000000..418e71f --- /dev/null +++ b/quic/qbone/bonnet/qbone_tunnel_silo.cc
@@ -0,0 +1,31 @@ +// Copyright (c) 2020 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/third_party/quiche/src/quic/qbone/bonnet/qbone_tunnel_silo.h" + +namespace quic { + +void QboneTunnelSilo::Run() { + while (ShouldRun()) { + tunnel_->WaitForEvents(); + } + + QUIC_LOG(INFO) << "Tunnel has disconnected in state: " + << tunnel_->StateToString(tunnel_->Disconnect()); +} + +void QboneTunnelSilo::Quit() { + QUIC_LOG(INFO) << "Quit called on QboneTunnelSilo"; + quitting_.Notify(); + tunnel_->Wake(); +} + +bool QboneTunnelSilo::ShouldRun() { + bool post_init_shutdown_ready = + only_setup_tun_ && + tunnel_->state() == quic::QboneTunnelInterface::STARTED; + return !quitting_.HasBeenNotified() && !post_init_shutdown_ready; +} + +} // namespace quic
diff --git a/quic/qbone/bonnet/qbone_tunnel_silo.h b/quic/qbone/bonnet/qbone_tunnel_silo.h new file mode 100644 index 0000000..8aad899 --- /dev/null +++ b/quic/qbone/bonnet/qbone_tunnel_silo.h
@@ -0,0 +1,48 @@ +// Copyright (c) 2020 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. + +#ifndef QUICHE_QUIC_QBONE_BONNET_QBONE_TUNNEL_SILO_H_ +#define QUICHE_QUIC_QBONE_BONNET_QBONE_TUNNEL_SILO_H_ + +#include "absl/synchronization/notification.h" +#include "net/third_party/quiche/src/quic/platform/api/quic_thread.h" +#include "net/third_party/quiche/src/quic/qbone/bonnet/qbone_tunnel_interface.h" + +namespace quic { + +// QboneTunnelSilo is a thread that initializes and evaluates a QboneTunnel's +// event loop. +class QboneTunnelSilo : public QuicThread { + public: + // Does not take ownership of |tunnel| + explicit QboneTunnelSilo(QboneTunnelInterface* tunnel, bool only_setup_tun) + : QuicThread("QboneTunnelSilo"), + tunnel_(tunnel), + only_setup_tun_(only_setup_tun) {} + + QboneTunnelSilo(const QboneTunnelSilo&) = delete; + QboneTunnelSilo& operator=(const QboneTunnelSilo&) = delete; + + QboneTunnelSilo(QboneTunnelSilo&&) = delete; + QboneTunnelSilo& operator=(QboneTunnelSilo&&) = delete; + + // Terminates the tunnel's event loop. This silo must still be joined. + void Quit(); + + protected: + void Run() override; + + private: + bool ShouldRun(); + + QboneTunnelInterface* tunnel_; + + absl::Notification quitting_; + + const bool only_setup_tun_; +}; + +} // namespace quic + +#endif // QUICHE_QUIC_QBONE_BONNET_QBONE_TUNNEL_SILO_H_
diff --git a/quic/qbone/bonnet/qbone_tunnel_silo_test.cc b/quic/qbone/bonnet/qbone_tunnel_silo_test.cc new file mode 100644 index 0000000..c2ff8ac --- /dev/null +++ b/quic/qbone/bonnet/qbone_tunnel_silo_test.cc
@@ -0,0 +1,78 @@ +// Copyright (c) 2020 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/third_party/quiche/src/quic/qbone/bonnet/qbone_tunnel_silo.h" + +#include "absl/synchronization/notification.h" +#include "net/third_party/quiche/src/quic/platform/api/quic_test.h" +#include "net/third_party/quiche/src/quic/qbone/bonnet/mock_qbone_tunnel.h" + +namespace quic { +namespace { + +using ::testing::Eq; +using ::testing::Invoke; +using ::testing::Return; + +TEST(QboneTunnelSiloTest, SiloRunsEventLoop) { + MockQboneTunnel mock_tunnel; + + absl::Notification event_loop_run; + EXPECT_CALL(mock_tunnel, WaitForEvents) + .WillRepeatedly(Invoke([&event_loop_run]() { + if (!event_loop_run.HasBeenNotified()) { + event_loop_run.Notify(); + } + return false; + })); + + QboneTunnelSilo silo(&mock_tunnel, false); + silo.Start(); + + event_loop_run.WaitForNotification(); + + absl::Notification client_disconnected; + EXPECT_CALL(mock_tunnel, Disconnect) + .WillOnce(Invoke([&client_disconnected]() { + client_disconnected.Notify(); + return QboneTunnelInterface::ENDED; + })); + + silo.Quit(); + client_disconnected.WaitForNotification(); + + silo.Join(); +} + +TEST(QboneTunnelSiloTest, SiloCanShutDownAfterInit) { + MockQboneTunnel mock_tunnel; + + int iteration_count = 0; + EXPECT_CALL(mock_tunnel, WaitForEvents) + .WillRepeatedly(Invoke([&iteration_count]() { + iteration_count++; + return false; + })); + + EXPECT_CALL(mock_tunnel, state) + .WillOnce(Return(QboneTunnelInterface::START_REQUESTED)) + .WillOnce(Return(QboneTunnelInterface::STARTED)); + + absl::Notification client_disconnected; + EXPECT_CALL(mock_tunnel, Disconnect) + .WillOnce(Invoke([&client_disconnected]() { + client_disconnected.Notify(); + return QboneTunnelInterface::ENDED; + })); + + QboneTunnelSilo silo(&mock_tunnel, true); + silo.Start(); + + client_disconnected.WaitForNotification(); + silo.Join(); + EXPECT_THAT(iteration_count, Eq(1)); +} + +} // namespace +} // namespace quic