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