blob: 81d0bf2a5f5ee43b2904941efe6b4d60d6605552 [file] [log] [blame]
// Copyright 2013 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_TEST_TOOLS_SERVER_THREAD_H_
#define QUICHE_QUIC_TEST_TOOLS_SERVER_THREAD_H_
#include <memory>
#include "quic/core/quic_config.h"
#include "quic/platform/api/quic_containers.h"
#include "quic/platform/api/quic_mutex.h"
#include "quic/platform/api/quic_socket_address.h"
#include "quic/platform/api/quic_thread.h"
#include "quic/tools/quic_server.h"
namespace quic {
namespace test {
// Simple wrapper class to run QuicServer in a dedicated thread.
class ServerThread : public QuicThread {
public:
ServerThread(QuicServer* server, const QuicSocketAddress& address);
ServerThread(const ServerThread&) = delete;
ServerThread& operator=(const ServerThread&) = delete;
~ServerThread() override;
// Prepares the server, but does not start accepting connections. Useful for
// injecting mocks.
void Initialize();
// Runs the event loop. Will initialize if necessary.
void Run() override;
// Schedules the given action for execution in the event loop.
void Schedule(std::function<void()> action);
// Waits for the handshake to be confirmed for the first session created.
void WaitForCryptoHandshakeConfirmed();
// Wait until |termination_predicate| returns true in server thread, or
// reached |timeout|. Must be called from an external thread.
// Return whether the function returned after |termination_predicate| become
// true.
bool WaitUntil(std::function<bool()> termination_predicate,
QuicTime::Delta timeout);
// Pauses execution of the server until Resume() is called. May only be
// called once.
void Pause();
// Resumes execution of the server after Pause() has been called. May only
// be called once.
void Resume();
// Stops the server from executing and shuts it down, destroying all
// server objects.
void Quit();
// Returns the underlying server. Care must be taken to avoid data races
// when accessing the server. It is always safe to access the server
// after calling Pause() and before calling Resume().
QuicServer* server() { return server_.get(); }
// Returns the port that the server is listening on.
int GetPort();
private:
void MaybeNotifyOfHandshakeConfirmation();
void ExecuteScheduledActions();
QuicNotification
confirmed_; // Notified when the first handshake is confirmed.
QuicNotification pause_; // Notified when the server should pause.
QuicNotification paused_; // Notitied when the server has paused
QuicNotification resume_; // Notified when the server should resume.
QuicNotification quit_; // Notified when the server should quit.
std::unique_ptr<QuicServer> server_;
QuicEpollClock clock_;
QuicSocketAddress address_;
mutable QuicMutex port_lock_;
int port_ QUIC_GUARDED_BY(port_lock_);
bool initialized_;
QuicMutex scheduled_actions_lock_;
quiche::QuicheCircularDeque<std::function<void()>> scheduled_actions_
QUIC_GUARDED_BY(scheduled_actions_lock_);
};
} // namespace test
} // namespace quic
#endif // QUICHE_QUIC_TEST_TOOLS_SERVER_THREAD_H_