1// 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/tools/quic/test_tools/server_thread.h"
6
7#include "net/tools/quic/quic_dispatcher.h"
8#include "net/tools/quic/test_tools/quic_server_peer.h"
9
10namespace net {
11namespace tools {
12namespace test {
13
14ServerThread::ServerThread(QuicServer* server,
15                           IPEndPoint address,
16                           bool strike_register_no_startup_period)
17    : SimpleThread("server_thread"),
18      confirmed_(true, false),
19      pause_(true, false),
20      paused_(true, false),
21      resume_(true, false),
22      quit_(true, false),
23      server_(server),
24      address_(address),
25      port_(0),
26      initialized_(false) {
27  if (strike_register_no_startup_period) {
28    server_->SetStrikeRegisterNoStartupPeriod();
29  }
30}
31
32ServerThread::~ServerThread() {}
33
34void ServerThread::Initialize() {
35  if (initialized_) {
36    return;
37  }
38
39  server_->Listen(address_);
40
41  port_lock_.Acquire();
42  port_ = server_->port();
43  port_lock_.Release();
44
45  initialized_ = true;
46}
47
48void ServerThread::Run() {
49  if (!initialized_) {
50    Initialize();
51  }
52
53  while (!quit_.IsSignaled()) {
54    if (pause_.IsSignaled() && !resume_.IsSignaled()) {
55      paused_.Signal();
56      resume_.Wait();
57    }
58    server_->WaitForEvents();
59    MaybeNotifyOfHandshakeConfirmation();
60  }
61
62  server_->Shutdown();
63}
64
65int ServerThread::GetPort() {
66  port_lock_.Acquire();
67  int rc = port_;
68  port_lock_.Release();
69  return rc;
70}
71
72void ServerThread::WaitForCryptoHandshakeConfirmed() {
73  confirmed_.Wait();
74}
75
76void ServerThread::Pause() {
77  DCHECK(!pause_.IsSignaled());
78  pause_.Signal();
79  paused_.Wait();
80}
81
82void ServerThread::Resume() {
83  DCHECK(!resume_.IsSignaled());
84  DCHECK(pause_.IsSignaled());
85  resume_.Signal();
86}
87
88void ServerThread::Quit() {
89  if (pause_.IsSignaled() && !resume_.IsSignaled()) {
90    resume_.Signal();
91  }
92  quit_.Signal();
93}
94
95void ServerThread::MaybeNotifyOfHandshakeConfirmation() {
96  if (confirmed_.IsSignaled()) {
97    // Only notify once.
98    return;
99  }
100  QuicDispatcher* dispatcher = QuicServerPeer::GetDispatcher(server());
101  if (dispatcher->session_map().empty()) {
102    // Wait for a session to be created.
103    return;
104  }
105  QuicSession* session = dispatcher->session_map().begin()->second;
106  if (session->IsCryptoHandshakeConfirmed()) {
107    confirmed_.Signal();
108  }
109}
110
111}  // namespace test
112}  // namespace tools
113}  // namespace net
114