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