blob: 77a23a656fec9ed922c8ed80f554a63c5757ac62 [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "net/third_party/quiche/src/quic/test_tools/server_thread.h"
6
7#include "net/third_party/quiche/src/quic/core/quic_dispatcher.h"
8#include "net/third_party/quiche/src/quic/platform/api/quic_containers.h"
9#include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h"
10#include "net/third_party/quiche/src/quic/test_tools/quic_server_peer.h"
11
12namespace quic {
13namespace test {
14
15ServerThread::ServerThread(QuicServer* server, const QuicSocketAddress& address)
16 : QuicThread("server_thread"),
17 server_(server),
wub051660f2020-02-06 11:51:50 -080018 clock_(server->epoll_server()),
QUICHE teama6ef0a62019-03-07 20:34:33 -050019 address_(address),
20 port_(0),
21 initialized_(false) {}
22
23ServerThread::~ServerThread() = default;
24
25void ServerThread::Initialize() {
26 if (initialized_) {
27 return;
28 }
29
30 server_->CreateUDPSocketAndListen(address_);
31
32 QuicWriterMutexLock lock(&port_lock_);
33 port_ = server_->port();
34
35 initialized_ = true;
36}
37
38void ServerThread::Run() {
39 if (!initialized_) {
40 Initialize();
41 }
42
43 while (!quit_.HasBeenNotified()) {
44 if (pause_.HasBeenNotified() && !resume_.HasBeenNotified()) {
45 paused_.Notify();
46 resume_.WaitForNotification();
47 }
48 server_->WaitForEvents();
49 ExecuteScheduledActions();
50 MaybeNotifyOfHandshakeConfirmation();
51 }
52
53 server_->Shutdown();
54}
55
56int ServerThread::GetPort() {
57 QuicReaderMutexLock lock(&port_lock_);
58 int rc = port_;
59 return rc;
60}
61
62void ServerThread::Schedule(std::function<void()> action) {
63 DCHECK(!quit_.HasBeenNotified());
64 QuicWriterMutexLock lock(&scheduled_actions_lock_);
65 scheduled_actions_.push_back(std::move(action));
66}
67
68void ServerThread::WaitForCryptoHandshakeConfirmed() {
69 confirmed_.WaitForNotification();
70}
71
wub051660f2020-02-06 11:51:50 -080072bool ServerThread::WaitUntil(std::function<bool()> termination_predicate,
73 QuicTime::Delta timeout) {
74 const QuicTime deadline = clock_.Now() + timeout;
75 while (clock_.Now() < deadline) {
76 QuicNotification done_checking;
77 bool should_terminate = false;
78 Schedule([&] {
79 should_terminate = termination_predicate();
80 done_checking.Notify();
81 });
82 done_checking.WaitForNotification();
83 if (should_terminate) {
84 return true;
85 }
86 }
87 return false;
88}
89
QUICHE teama6ef0a62019-03-07 20:34:33 -050090void ServerThread::Pause() {
91 DCHECK(!pause_.HasBeenNotified());
92 pause_.Notify();
93 paused_.WaitForNotification();
94}
95
96void ServerThread::Resume() {
97 DCHECK(!resume_.HasBeenNotified());
98 DCHECK(pause_.HasBeenNotified());
99 resume_.Notify();
100}
101
102void ServerThread::Quit() {
103 if (pause_.HasBeenNotified() && !resume_.HasBeenNotified()) {
104 resume_.Notify();
105 }
106 if (!quit_.HasBeenNotified()) {
107 quit_.Notify();
108 }
109}
110
111void ServerThread::MaybeNotifyOfHandshakeConfirmation() {
112 if (confirmed_.HasBeenNotified()) {
113 // Only notify once.
114 return;
115 }
116 QuicDispatcher* dispatcher = QuicServerPeer::GetDispatcher(server());
117 if (dispatcher->session_map().empty()) {
118 // Wait for a session to be created.
119 return;
120 }
121 QuicSession* session = dispatcher->session_map().begin()->second.get();
fayanga3d8df72020-01-14 11:54:39 -0800122 if (session->OneRttKeysAvailable()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500123 confirmed_.Notify();
124 }
125}
126
127void ServerThread::ExecuteScheduledActions() {
wuba750aab2020-02-10 06:43:15 -0800128 QuicCircularDeque<std::function<void()>> actions;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500129 {
130 QuicWriterMutexLock lock(&scheduled_actions_lock_);
131 actions.swap(scheduled_actions_);
132 }
133 while (!actions.empty()) {
134 actions.front()();
135 actions.pop_front();
136 }
137}
138
139} // namespace test
140} // namespace quic