diff --git a/build/source_list.bzl b/build/source_list.bzl
index fa32a50..808114a 100644
--- a/build/source_list.bzl
+++ b/build/source_list.bzl
@@ -948,10 +948,6 @@
     "common/platform/api/quiche_event_loop.h",
     "common/platform/api/quiche_stream_buffer_allocator.h",
     "common/platform/api/quiche_udp_socket_platform_api.h",
-    "epoll_server/platform/api/epoll_bug.h",
-    "epoll_server/platform/api/epoll_logging.h",
-    "epoll_server/platform/api/epoll_thread.h",
-    "epoll_server/simple_epoll_server.h",
     "quic/core/batch_writer/quic_batch_writer_base.h",
     "quic/core/batch_writer/quic_batch_writer_buffer.h",
     "quic/core/batch_writer/quic_batch_writer_test.h",
@@ -984,7 +980,6 @@
     "quic/tools/quic_server.h",
 ]
 epoll_tool_support_srcs = [
-    "epoll_server/simple_epoll_server.cc",
     "quic/core/batch_writer/quic_batch_writer_base.cc",
     "quic/core/batch_writer/quic_batch_writer_buffer.cc",
     "quic/core/batch_writer/quic_gso_batch_writer.cc",
@@ -1012,10 +1007,6 @@
     "quic/tools/quic_server.cc",
 ]
 epoll_test_support_hdrs = [
-    "epoll_server/fake_simple_epoll_server.h",
-    "epoll_server/platform/api/epoll_address_test_utils.h",
-    "epoll_server/platform/api/epoll_expect_bug.h",
-    "epoll_server/platform/api/epoll_test.h",
     "quic/bindings/quic_libevent.h",
     "quic/test_tools/quic_mock_syscall_wrapper.h",
     "quic/test_tools/quic_server_peer.h",
@@ -1024,7 +1015,6 @@
     "quic/test_tools/server_thread.h",
 ]
 epoll_test_support_srcs = [
-    "epoll_server/fake_simple_epoll_server.cc",
     "quic/bindings/quic_libevent.cc",
     "quic/test_tools/quic_mock_syscall_wrapper.cc",
     "quic/test_tools/quic_server_peer.cc",
@@ -1296,7 +1286,6 @@
 
 ]
 epoll_tests_srcs = [
-    "epoll_server/simple_epoll_server_test.cc",
     "quic/core/batch_writer/quic_batch_writer_buffer_test.cc",
     "quic/core/batch_writer/quic_batch_writer_test.cc",
     "quic/core/batch_writer/quic_gso_batch_writer_test.cc",
diff --git a/build/source_list.gni b/build/source_list.gni
index d36d591..a03ebc5 100644
--- a/build/source_list.gni
+++ b/build/source_list.gni
@@ -948,10 +948,6 @@
     "src/quiche/common/platform/api/quiche_event_loop.h",
     "src/quiche/common/platform/api/quiche_stream_buffer_allocator.h",
     "src/quiche/common/platform/api/quiche_udp_socket_platform_api.h",
-    "src/quiche/epoll_server/platform/api/epoll_bug.h",
-    "src/quiche/epoll_server/platform/api/epoll_logging.h",
-    "src/quiche/epoll_server/platform/api/epoll_thread.h",
-    "src/quiche/epoll_server/simple_epoll_server.h",
     "src/quiche/quic/core/batch_writer/quic_batch_writer_base.h",
     "src/quiche/quic/core/batch_writer/quic_batch_writer_buffer.h",
     "src/quiche/quic/core/batch_writer/quic_batch_writer_test.h",
@@ -984,7 +980,6 @@
     "src/quiche/quic/tools/quic_server.h",
 ]
 epoll_tool_support_srcs = [
-    "src/quiche/epoll_server/simple_epoll_server.cc",
     "src/quiche/quic/core/batch_writer/quic_batch_writer_base.cc",
     "src/quiche/quic/core/batch_writer/quic_batch_writer_buffer.cc",
     "src/quiche/quic/core/batch_writer/quic_gso_batch_writer.cc",
@@ -1012,10 +1007,6 @@
     "src/quiche/quic/tools/quic_server.cc",
 ]
 epoll_test_support_hdrs = [
-    "src/quiche/epoll_server/fake_simple_epoll_server.h",
-    "src/quiche/epoll_server/platform/api/epoll_address_test_utils.h",
-    "src/quiche/epoll_server/platform/api/epoll_expect_bug.h",
-    "src/quiche/epoll_server/platform/api/epoll_test.h",
     "src/quiche/quic/bindings/quic_libevent.h",
     "src/quiche/quic/test_tools/quic_mock_syscall_wrapper.h",
     "src/quiche/quic/test_tools/quic_server_peer.h",
@@ -1024,7 +1015,6 @@
     "src/quiche/quic/test_tools/server_thread.h",
 ]
 epoll_test_support_srcs = [
-    "src/quiche/epoll_server/fake_simple_epoll_server.cc",
     "src/quiche/quic/bindings/quic_libevent.cc",
     "src/quiche/quic/test_tools/quic_mock_syscall_wrapper.cc",
     "src/quiche/quic/test_tools/quic_server_peer.cc",
@@ -1296,7 +1286,6 @@
 
 ]
 epoll_tests_srcs = [
-    "src/quiche/epoll_server/simple_epoll_server_test.cc",
     "src/quiche/quic/core/batch_writer/quic_batch_writer_buffer_test.cc",
     "src/quiche/quic/core/batch_writer/quic_batch_writer_test.cc",
     "src/quiche/quic/core/batch_writer/quic_gso_batch_writer_test.cc",
diff --git a/build/source_list.json b/build/source_list.json
index 753c2fd..cf5abb2 100644
--- a/build/source_list.json
+++ b/build/source_list.json
@@ -947,10 +947,6 @@
     "quiche/common/platform/api/quiche_event_loop.h",
     "quiche/common/platform/api/quiche_stream_buffer_allocator.h",
     "quiche/common/platform/api/quiche_udp_socket_platform_api.h",
-    "quiche/epoll_server/platform/api/epoll_bug.h",
-    "quiche/epoll_server/platform/api/epoll_logging.h",
-    "quiche/epoll_server/platform/api/epoll_thread.h",
-    "quiche/epoll_server/simple_epoll_server.h",
     "quiche/quic/core/batch_writer/quic_batch_writer_base.h",
     "quiche/quic/core/batch_writer/quic_batch_writer_buffer.h",
     "quiche/quic/core/batch_writer/quic_batch_writer_test.h",
@@ -983,7 +979,6 @@
     "quiche/quic/tools/quic_server.h"
   ],
   "epoll_tool_support_srcs": [
-    "quiche/epoll_server/simple_epoll_server.cc",
     "quiche/quic/core/batch_writer/quic_batch_writer_base.cc",
     "quiche/quic/core/batch_writer/quic_batch_writer_buffer.cc",
     "quiche/quic/core/batch_writer/quic_gso_batch_writer.cc",
@@ -1011,10 +1006,6 @@
     "quiche/quic/tools/quic_server.cc"
   ],
   "epoll_test_support_hdrs": [
-    "quiche/epoll_server/fake_simple_epoll_server.h",
-    "quiche/epoll_server/platform/api/epoll_address_test_utils.h",
-    "quiche/epoll_server/platform/api/epoll_expect_bug.h",
-    "quiche/epoll_server/platform/api/epoll_test.h",
     "quiche/quic/bindings/quic_libevent.h",
     "quiche/quic/test_tools/quic_mock_syscall_wrapper.h",
     "quiche/quic/test_tools/quic_server_peer.h",
@@ -1023,7 +1014,6 @@
     "quiche/quic/test_tools/server_thread.h"
   ],
   "epoll_test_support_srcs": [
-    "quiche/epoll_server/fake_simple_epoll_server.cc",
     "quiche/quic/bindings/quic_libevent.cc",
     "quiche/quic/test_tools/quic_mock_syscall_wrapper.cc",
     "quiche/quic/test_tools/quic_server_peer.cc",
@@ -1295,7 +1285,6 @@
 
   ],
   "epoll_tests_srcs": [
-    "quiche/epoll_server/simple_epoll_server_test.cc",
     "quiche/quic/core/batch_writer/quic_batch_writer_buffer_test.cc",
     "quiche/quic/core/batch_writer/quic_batch_writer_test.cc",
     "quiche/quic/core/batch_writer/quic_gso_batch_writer_test.cc",
diff --git a/quiche/epoll_server/fake_simple_epoll_server.cc b/quiche/epoll_server/fake_simple_epoll_server.cc
deleted file mode 100644
index f21ae1c..0000000
--- a/quiche/epoll_server/fake_simple_epoll_server.cc
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright (c) 2012 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.
-
-#include "quiche/epoll_server/fake_simple_epoll_server.h"
-
-namespace epoll_server {
-namespace test {
-
-FakeTimeSimpleEpollServer::FakeTimeSimpleEpollServer() : now_in_usec_(0) {}
-
-FakeTimeSimpleEpollServer::~FakeTimeSimpleEpollServer() = default;
-
-int64_t FakeTimeSimpleEpollServer::NowInUsec() const { return now_in_usec_; }
-
-FakeSimpleEpollServer::FakeSimpleEpollServer() : until_in_usec_(-1) {}
-
-FakeSimpleEpollServer::~FakeSimpleEpollServer() = default;
-
-int FakeSimpleEpollServer::epoll_wait_impl(int /*epfd*/,
-                                           struct epoll_event* events,
-                                           int max_events, int timeout_in_ms) {
-  int num_events = 0;
-  while (!event_queue_.empty() && num_events < max_events &&
-         event_queue_.begin()->first <= NowInUsec() &&
-         ((until_in_usec_ == -1) ||
-          (event_queue_.begin()->first < until_in_usec_))) {
-    int64_t event_time_in_usec = event_queue_.begin()->first;
-    events[num_events] = event_queue_.begin()->second;
-    if (event_time_in_usec > NowInUsec()) {
-      set_now_in_usec(event_time_in_usec);
-    }
-    event_queue_.erase(event_queue_.begin());
-    ++num_events;
-  }
-  if (num_events == 0) {       // then we'd have waited 'till the timeout.
-    if (until_in_usec_ < 0) {  // then we don't care what the final time is.
-      if (timeout_in_ms > 0) {
-        AdvanceBy(timeout_in_ms * 1000);
-      }
-    } else {  // except we assume that we don't wait for the timeout
-      // period if until_in_usec_ is a positive number.
-      set_now_in_usec(until_in_usec_);
-      // And reset until_in_usec_ to signal no waiting (as
-      // the AdvanceByExactly* stuff is meant to be one-shot,
-      // as are all similar net::EpollServer functions)
-      until_in_usec_ = -1;
-    }
-  }
-  if (until_in_usec_ >= 0) {
-    CHECK(until_in_usec_ >= NowInUsec());
-  }
-  return num_events;
-}
-
-}  // namespace test
-}  // namespace epoll_server
diff --git a/quiche/epoll_server/fake_simple_epoll_server.h b/quiche/epoll_server/fake_simple_epoll_server.h
deleted file mode 100644
index 62c9dd1..0000000
--- a/quiche/epoll_server/fake_simple_epoll_server.h
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright (c) 2012 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_EPOLL_SERVER_FAKE_SIMPLE_EPOLL_SERVER_H_
-#define QUICHE_EPOLL_SERVER_FAKE_SIMPLE_EPOLL_SERVER_H_
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <map>
-
-#include "quiche/epoll_server/simple_epoll_server.h"
-
-namespace epoll_server {
-namespace test {
-
-// Unlike the full FakeEpollServer, this only lies about the time but lets
-// fd events operate normally.  Usefully when interacting with real backends
-// but wanting to skip forward in time to trigger timeouts.
-class FakeTimeSimpleEpollServer : public SimpleEpollServer {
- public:
-  FakeTimeSimpleEpollServer();
-  FakeTimeSimpleEpollServer(const FakeTimeSimpleEpollServer&) = delete;
-  FakeTimeSimpleEpollServer operator=(const FakeTimeSimpleEpollServer&) =
-      delete;
-
-  ~FakeTimeSimpleEpollServer() override;
-
-  // Replaces the net::EpollServer NowInUsec.
-  int64_t NowInUsec() const override;
-
-  void set_now_in_usec(int64_t nius) { now_in_usec_ = nius; }
-
-  // Advances the virtual 'now' by advancement_usec.
-  void AdvanceBy(int64_t advancement_usec) {
-    set_now_in_usec(NowInUsec() + advancement_usec);
-  }
-
-  // Advances the virtual 'now' by advancement_usec, and
-  // calls WaitForEventAndExecteCallbacks.
-  // Note that the WaitForEventsAndExecuteCallbacks invocation
-  // may cause NowInUs to advance beyond what was specified here.
-  // If that is not desired, use the AdvanceByExactly calls.
-  void AdvanceByAndWaitForEventsAndExecuteCallbacks(int64_t advancement_usec) {
-    AdvanceBy(advancement_usec);
-    WaitForEventsAndExecuteCallbacks();
-  }
-
- private:
-  int64_t now_in_usec_;
-};
-
-class FakeSimpleEpollServer : public FakeTimeSimpleEpollServer {
- public:  // type definitions
-  using EventQueue = std::multimap<int64_t, struct epoll_event>;
-
-  FakeSimpleEpollServer();
-  FakeSimpleEpollServer(const FakeSimpleEpollServer&) = delete;
-  FakeSimpleEpollServer operator=(const FakeSimpleEpollServer&) = delete;
-
-  ~FakeSimpleEpollServer() override;
-
-  // time_in_usec is the time at which the event specified
-  // by 'ee' will be delivered. Note that it -is- possible
-  // to add an event for a time which has already been passed..
-  // .. upon the next time that the callbacks are invoked,
-  // all events which are in the 'past' will be delivered.
-  void AddEvent(int64_t time_in_usec, const struct epoll_event& ee) {
-    event_queue_.insert(std::make_pair(time_in_usec, ee));
-  }
-
-  // Advances the virtual 'now' by advancement_usec,
-  // and ensure that the next invocation of
-  // WaitForEventsAndExecuteCallbacks goes no farther than
-  // advancement_usec from the current time.
-  void AdvanceByExactly(int64_t advancement_usec) {
-    until_in_usec_ = NowInUsec() + advancement_usec;
-    set_now_in_usec(NowInUsec() + advancement_usec);
-  }
-
-  // As above, except calls WaitForEventsAndExecuteCallbacks.
-  void AdvanceByExactlyAndCallCallbacks(int64_t advancement_usec) {
-    AdvanceByExactly(advancement_usec);
-    WaitForEventsAndExecuteCallbacks();
-  }
-
-  std::unordered_set<AlarmCB*>::size_type NumberOfAlarms() const {
-    return all_alarms_.size();
-  }
-
- protected:  // functions
-  // These functions do nothing here, as we're not actually
-  // using the epoll_* syscalls.
-  void DelFD(int /*fd*/) const override {}
-  void AddFD(int /*fd*/, int /*event_mask*/) const override {}
-  void ModFD(int /*fd*/, int /*event_mask*/) const override {}
-
-  // Replaces the epoll_server's epoll_wait_impl.
-  int epoll_wait_impl(int epfd, struct epoll_event* events, int max_events,
-                      int timeout_in_ms) override;
-  void SetNonblocking(int /*fd*/) override {}
-
- private:  // members
-  EventQueue event_queue_;
-  int64_t until_in_usec_;
-};
-
-}  // namespace test
-}  // namespace epoll_server
-
-#endif  // QUICHE_EPOLL_SERVER_FAKE_SIMPLE_EPOLL_SERVER_H_
diff --git a/quiche/epoll_server/platform/api/epoll_address_test_utils.h b/quiche/epoll_server/platform/api/epoll_address_test_utils.h
deleted file mode 100644
index 883d510..0000000
--- a/quiche/epoll_server/platform/api/epoll_address_test_utils.h
+++ /dev/null
@@ -1,16 +0,0 @@
-// 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_EPOLL_SERVER_PLATFORM_API_EPOLL_ADDRESS_TEST_UTILS_H_
-#define QUICHE_EPOLL_SERVER_PLATFORM_API_EPOLL_ADDRESS_TEST_UTILS_H_
-
-#include "quiche_platform_impl/epoll_address_test_utils_impl.h"
-
-namespace epoll_server {
-
-inline int AddressFamilyUnderTest() { return AddressFamilyUnderTestImpl(); }
-
-}  // namespace epoll_server
-
-#endif  // QUICHE_EPOLL_SERVER_PLATFORM_API_EPOLL_ADDRESS_TEST_UTILS_H_
diff --git a/quiche/epoll_server/platform/api/epoll_bug.h b/quiche/epoll_server/platform/api/epoll_bug.h
deleted file mode 100644
index eeb707a..0000000
--- a/quiche/epoll_server/platform/api/epoll_bug.h
+++ /dev/null
@@ -1,12 +0,0 @@
-// 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_EPOLL_SERVER_PLATFORM_API_EPOLL_BUG_H_
-#define QUICHE_EPOLL_SERVER_PLATFORM_API_EPOLL_BUG_H_
-
-#include "quiche_platform_impl/epoll_bug_impl.h"
-
-#define EPOLL_BUG EPOLL_BUG_IMPL
-
-#endif  // QUICHE_EPOLL_SERVER_PLATFORM_API_EPOLL_BUG_H_
diff --git a/quiche/epoll_server/platform/api/epoll_expect_bug.h b/quiche/epoll_server/platform/api/epoll_expect_bug.h
deleted file mode 100644
index 36ebd97..0000000
--- a/quiche/epoll_server/platform/api/epoll_expect_bug.h
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2018 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_EPOLL_SERVER_PLATFORM_API_EPOLL_EXPECT_BUG_H_
-#define QUICHE_EPOLL_SERVER_PLATFORM_API_EPOLL_EXPECT_BUG_H_
-
-#include "quiche_platform_impl/epoll_expect_bug_impl.h"
-
-#define EXPECT_EPOLL_BUG EXPECT_EPOLL_BUG_IMPL
-
-#endif  // QUICHE_EPOLL_SERVER_PLATFORM_API_EPOLL_EXPECT_BUG_H_
diff --git a/quiche/epoll_server/platform/api/epoll_logging.h b/quiche/epoll_server/platform/api/epoll_logging.h
deleted file mode 100644
index 2d5a0f4..0000000
--- a/quiche/epoll_server/platform/api/epoll_logging.h
+++ /dev/null
@@ -1,19 +0,0 @@
-// 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_EPOLL_SERVER_PLATFORM_API_EPOLL_LOGGING_H_
-#define QUICHE_EPOLL_SERVER_PLATFORM_API_EPOLL_LOGGING_H_
-
-#include "quiche_platform_impl/epoll_logging_impl.h"
-
-namespace epoll_server {
-
-#define EPOLL_LOG(severity) EPOLL_LOG_IMPL(severity)
-#define EPOLL_VLOG(verbosity) EPOLL_VLOG_IMPL(verbosity)
-#define EPOLL_DVLOG(verbosity) EPOLL_DVLOG_IMPL(verbosity)
-#define EPOLL_PLOG(severity) EPOLL_PLOG_IMPL(severity)
-
-}  // namespace epoll_server
-
-#endif  // QUICHE_EPOLL_SERVER_PLATFORM_API_EPOLL_LOGGING_H_
diff --git a/quiche/epoll_server/platform/api/epoll_test.h b/quiche/epoll_server/platform/api/epoll_test.h
deleted file mode 100644
index c7f0eea..0000000
--- a/quiche/epoll_server/platform/api/epoll_test.h
+++ /dev/null
@@ -1,11 +0,0 @@
-// 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_EPOLL_SERVER_PLATFORM_API_EPOLL_TEST_H_
-#define QUICHE_EPOLL_SERVER_PLATFORM_API_EPOLL_TEST_H_
-
-#include "quiche_platform_impl/epoll_test_impl.h"
-#define EpollTest EpollTestImpl
-
-#endif  // QUICHE_EPOLL_SERVER_PLATFORM_API_EPOLL_TEST_H_
diff --git a/quiche/epoll_server/platform/api/epoll_thread.h b/quiche/epoll_server/platform/api/epoll_thread.h
deleted file mode 100644
index 5b159cb..0000000
--- a/quiche/epoll_server/platform/api/epoll_thread.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// 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_EPOLL_SERVER_PLATFORM_API_EPOLL_THREAD_H_
-#define QUICHE_EPOLL_SERVER_PLATFORM_API_EPOLL_THREAD_H_
-
-#include <string>
-
-#include "quiche_platform_impl/epoll_thread_impl.h"
-
-namespace epoll_server {
-
-// A class representing a thread of execution in QUIC.
-class EpollThread : public EpollThreadImpl {
- public:
-  EpollThread(const std::string& string) : EpollThreadImpl(string) {}
-  EpollThread(const EpollThread&) = delete;
-  EpollThread& operator=(const EpollThread&) = delete;
-
-  // Impl defines a virtual void Run() method which subclasses
-  // must implement.
-};
-
-}  // namespace epoll_server
-
-#endif  // QUICHE_EPOLL_SERVER_PLATFORM_API_EPOLL_THREAD_H_
diff --git a/quiche/epoll_server/simple_epoll_server.cc b/quiche/epoll_server/simple_epoll_server.cc
deleted file mode 100644
index eb9d6c4..0000000
--- a/quiche/epoll_server/simple_epoll_server.cc
+++ /dev/null
@@ -1,815 +0,0 @@
-// 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.
-
-#include "quiche/epoll_server/simple_epoll_server.h"
-
-#include <errno.h>   // for errno
-#include <stdlib.h>  // for abort
-#include <string.h>  // for strerror_r
-#include <unistd.h>  // For read, pipe, close and write.
-
-#include <algorithm>
-#include <utility>
-
-#include "absl/time/clock.h"
-#include "quiche/epoll_server/platform/api/epoll_bug.h"
-
-// Design notes: An efficient implementation of ready list has the following
-// desirable properties:
-//
-// A. O(1) insertion into/removal from the list in any location.
-// B. Once the callback is found by hash lookup using the fd, the lookup of
-//    corresponding entry in the list is O(1).
-// C. Safe insertion into/removal from the list during list iteration. (The
-//    ready list's purpose is to enable completely event driven I/O model.
-//    Thus, all the interesting bits happen in the callback. It is critical
-//    to not place any restriction on the API during list iteration.
-//
-// The current implementation achieves these goals with the following design:
-//
-// - The ready list is constructed as a doubly linked list to enable O(1)
-//   insertion/removal (see man 3 queue).
-// - The forward and backward links are directly embedded inside the
-//   CBAndEventMask struct. This enables O(1) lookup in the list for a given
-//   callback. (Techincally, we could've used std::list of hash_set::iterator,
-//   and keep a list::iterator in CBAndEventMask to achieve the same effect.
-//   However, iterators have two problems: no way to portably invalidate them,
-//   and no way to tell whether an iterator is singular or not. The only way to
-//   overcome these issues is to keep bools in both places, but that throws off
-//   memory alignment (up to 7 wasted bytes for each bool). The extra level of
-//   indirection will also likely be less cache friendly. Direct manipulation
-//   of link pointers makes it easier to retrieve the CBAndEventMask from the
-//   list, easier to check whether an CBAndEventMask is in the list, uses less
-//   memory (save 32 bytes/fd), and does not affect cache usage (we need to
-//   read in the struct to use the callback anyway).)
-// - Embed the fd directly into CBAndEventMask and switch to using hash_set.
-//   This removes the need to store hash_map::iterator in the list just so that
-//   we can get both the fd and the callback.
-// - The ready list is "one shot": each entry is removed before OnEvent is
-//   called. This removes the mutation-while-iterating problem.
-// - Use two lists to keep track of callbacks. The ready_list_ is the one used
-//   for registration. Before iteration, the ready_list_ is swapped into the
-//   tmp_list_. Once iteration is done, tmp_list_ will be empty, and
-//   ready_list_ will have all the new ready fds.
-
-// The size we use for buffers passed to strerror_r
-static const int kErrorBufferSize = 256;
-
-namespace epoll_server {
-
-template <typename T>
-class AutoReset {
- public:
-  AutoReset(T* scoped_variable, T new_value)
-      : scoped_variable_(scoped_variable),
-        original_value_(std::move(*scoped_variable)) {
-    *scoped_variable_ = std::move(new_value);
-  }
-  AutoReset(const AutoReset&) = delete;
-  AutoReset& operator=(const AutoReset&) = delete;
-
-  ~AutoReset() { *scoped_variable_ = std::move(original_value_); }
-
- private:
-  T* scoped_variable_;
-  T original_value_;
-};
-
-// Clears the pipe and returns.  Used for waking the epoll server up.
-class ReadPipeCallback : public EpollCallbackInterface {
- public:
-  void OnEvent(int fd, EpollEvent* event) override {
-    DCHECK(event->in_events == EPOLLIN);
-    int data;
-    int data_read = 1;
-    // Read until the pipe is empty.
-    while (data_read > 0) {
-      data_read = read(fd, &data, sizeof(data));
-    }
-  }
-  void OnShutdown(SimpleEpollServer* /*eps*/, int /*fd*/) override {}
-  void OnRegistration(SimpleEpollServer*, int, int) override {}
-  void OnModification(int, int) override {}     // COV_NF_LINE
-  void OnUnregistration(int, bool) override {}  // COV_NF_LINE
-  std::string Name() const override { return "ReadPipeCallback"; }
-};
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-
-SimpleEpollServer::SimpleEpollServer()
-    : epoll_fd_(epoll_create(1024)),
-      timeout_in_us_(0),
-      recorded_now_in_us_(0),
-      ready_list_size_(0),
-      wake_cb_(new ReadPipeCallback),
-      read_fd_(-1),
-      write_fd_(-1),
-      in_wait_for_events_and_execute_callbacks_(false),
-      in_shutdown_(false),
-      last_delay_in_usec_(0) {
-  // ensure that the epoll_fd_ is valid.
-  CHECK_NE(epoll_fd_, -1);
-  LIST_INIT(&ready_list_);
-  LIST_INIT(&tmp_list_);
-
-  int pipe_fds[2];
-  if (pipe(pipe_fds) < 0) {
-    // Unfortunately, it is impossible to test any such initialization in
-    // a constructor (as virtual methods do not yet work).
-    // This -could- be solved by moving initialization to an outside
-    // call...
-    int saved_errno = errno;
-    char buf[kErrorBufferSize];
-    EPOLL_LOG(FATAL) << "Error " << saved_errno << " in pipe(): "
-                     << strerror_r(saved_errno, buf, sizeof(buf));
-  }
-  read_fd_ = pipe_fds[0];
-  write_fd_ = pipe_fds[1];
-  RegisterFD(read_fd_, wake_cb_.get(), EPOLLIN);
-}
-
-void SimpleEpollServer::CleanupFDToCBMap() {
-  auto cb_iter = cb_map_.begin();
-  while (cb_iter != cb_map_.end()) {
-    int fd = cb_iter->fd;
-    CB* cb = cb_iter->cb;
-
-    cb_iter->in_use = true;
-    if (cb) {
-      cb->OnShutdown(this, fd);
-    }
-
-    cb_map_.erase(cb_iter);
-    cb_iter = cb_map_.begin();
-  }
-}
-
-void SimpleEpollServer::CleanupTimeToAlarmCBMap() {
-  TimeToAlarmCBMap::iterator erase_it;
-
-  // Call OnShutdown() on alarms. Note that the structure of the loop
-  // is similar to the structure of loop in the function HandleAlarms()
-  for (auto i = alarm_map_.begin(); i != alarm_map_.end();) {
-    // Note that OnShutdown() can call UnregisterAlarm() on
-    // other iterators. OnShutdown() should not call UnregisterAlarm()
-    // on self because by definition the iterator is not valid any more.
-    i->second->OnShutdown(this);
-    erase_it = i;
-    ++i;
-    alarm_map_.erase(erase_it);
-  }
-}
-
-SimpleEpollServer::~SimpleEpollServer() {
-  DCHECK_EQ(in_shutdown_, false);
-  in_shutdown_ = true;
-#ifdef EPOLL_SERVER_EVENT_TRACING
-  EPOLL_LOG(INFO) << "\n" << event_recorder_;
-#endif
-  EPOLL_VLOG(2) << "Shutting down epoll server ";
-  CleanupFDToCBMap();
-
-  LIST_INIT(&ready_list_);
-  LIST_INIT(&tmp_list_);
-
-  CleanupTimeToAlarmCBMap();
-
-  close(read_fd_);
-  close(write_fd_);
-  close(epoll_fd_);
-}
-
-// Whether a CBAandEventMask is on the ready list is determined by a non-NULL
-// le_prev pointer (le_next being NULL indicates end of list).
-inline void SimpleEpollServer::AddToReadyList(CBAndEventMask* cb_and_mask) {
-  if (cb_and_mask->entry.le_prev == NULL) {
-    LIST_INSERT_HEAD(&ready_list_, cb_and_mask, entry);
-    ++ready_list_size_;
-  }
-}
-
-inline void SimpleEpollServer::RemoveFromReadyList(
-    const CBAndEventMask& cb_and_mask) {
-  if (cb_and_mask.entry.le_prev != NULL) {
-    LIST_REMOVE(&cb_and_mask, entry);
-    // Clean up all the ready list states. Don't bother with the other fields
-    // as they are initialized when the CBAandEventMask is added to the ready
-    // list. This saves a few cycles in the inner loop.
-    cb_and_mask.entry.le_prev = NULL;
-    --ready_list_size_;
-    if (ready_list_size_ == 0) {
-      DCHECK(ready_list_.lh_first == NULL);
-      DCHECK(tmp_list_.lh_first == NULL);
-    }
-  }
-}
-
-void SimpleEpollServer::RegisterFD(int fd, CB* cb, int event_mask) {
-  CHECK(cb);
-  EPOLL_VLOG(3) << "RegisterFD fd=" << fd << " event_mask=" << event_mask;
-  auto fd_i = cb_map_.find(CBAndEventMask(NULL, 0, fd));
-  if (cb_map_.end() != fd_i) {
-    // do we just abort, or do we just unregister the other callback?
-    // for now, lets just unregister the other callback.
-
-    // unregister any callback that may already be registered for this FD.
-    CB* other_cb = fd_i->cb;
-    if (other_cb) {
-      // Must remove from the ready list before erasing.
-      RemoveFromReadyList(*fd_i);
-      other_cb->OnUnregistration(fd, true);
-      ModFD(fd, event_mask);
-    } else {
-      // already unregistered, so just recycle the node.
-      AddFD(fd, event_mask);
-    }
-    fd_i->cb = cb;
-    fd_i->event_mask = event_mask;
-    fd_i->events_to_fake = 0;
-  } else {
-    AddFD(fd, event_mask);
-    cb_map_.insert(CBAndEventMask(cb, event_mask, fd));
-  }
-
-  // set the FD to be non-blocking.
-  SetNonblocking(fd);
-
-  cb->OnRegistration(this, fd, event_mask);
-}
-
-void SimpleEpollServer::SetNonblocking(int fd) {
-  int flags = fcntl(fd, F_GETFL, 0);
-  if (flags == -1) {
-    int saved_errno = errno;
-    char buf[kErrorBufferSize];
-    EPOLL_LOG(FATAL) << "Error " << saved_errno << " doing fcntl(" << fd
-                     << ", F_GETFL, 0): "
-                     << strerror_r(saved_errno, buf, sizeof(buf));
-  }
-  if (!(flags & O_NONBLOCK)) {
-    int saved_flags = flags;
-    flags = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
-    if (flags == -1) {
-      // bad.
-      int saved_errno = errno;
-      char buf[kErrorBufferSize];
-      EPOLL_LOG(FATAL) << "Error " << saved_errno << " doing fcntl(" << fd
-                       << ", F_SETFL, " << saved_flags
-                       << "): " << strerror_r(saved_errno, buf, sizeof(buf));
-    }
-  }
-}
-
-int SimpleEpollServer::epoll_wait_impl(int epfd, struct epoll_event* events,
-                                       int max_events, int timeout_in_ms) {
-  return epoll_wait(epfd, events, max_events, timeout_in_ms);
-}
-
-void SimpleEpollServer::RegisterFDForWrite(int fd, CB* cb) {
-  RegisterFD(fd, cb, EPOLLOUT);
-}
-
-void SimpleEpollServer::RegisterFDForReadWrite(int fd, CB* cb) {
-  RegisterFD(fd, cb, EPOLLIN | EPOLLOUT);
-}
-
-void SimpleEpollServer::RegisterFDForRead(int fd, CB* cb) {
-  RegisterFD(fd, cb, EPOLLIN);
-}
-
-void SimpleEpollServer::UnregisterFD(int fd) {
-  auto fd_i = cb_map_.find(CBAndEventMask(NULL, 0, fd));
-  if (cb_map_.end() == fd_i || fd_i->cb == NULL) {
-    // Doesn't exist in server, or has gone through UnregisterFD once and still
-    // inside the callchain of OnEvent.
-    return;
-  }
-#ifdef EPOLL_SERVER_EVENT_TRACING
-  event_recorder_.RecordUnregistration(fd);
-#endif
-  CB* cb = fd_i->cb;
-  // Since the links are embedded within the struct, we must remove it from the
-  // list before erasing it from the hash_set.
-  RemoveFromReadyList(*fd_i);
-  DelFD(fd);
-  cb->OnUnregistration(fd, false);
-  // fd_i->cb is NULL if that fd is unregistered inside the callchain of
-  // OnEvent. Since the SimpleEpollServer needs a valid CBAndEventMask after
-  // OnEvent returns in order to add it to the ready list, we cannot have
-  // UnregisterFD erase the entry if it is in use. Thus, a NULL fd_i->cb is used
-  // as a condition that tells the SimpleEpollServer that this entry is unused
-  // at a later point.
-  if (!fd_i->in_use) {
-    cb_map_.erase(fd_i);
-  } else {
-    // Remove all trace of the registration, and just keep the node alive long
-    // enough so the code that calls OnEvent doesn't have to worry about
-    // figuring out whether the CBAndEventMask is valid or not.
-    fd_i->cb = NULL;
-    fd_i->event_mask = 0;
-    fd_i->events_to_fake = 0;
-  }
-}
-
-void SimpleEpollServer::ModifyCallback(int fd, int event_mask) {
-  ModifyFD(fd, ~0, event_mask);
-}
-
-void SimpleEpollServer::StopRead(int fd) { ModifyFD(fd, EPOLLIN, 0); }
-
-void SimpleEpollServer::StartRead(int fd) { ModifyFD(fd, 0, EPOLLIN); }
-
-void SimpleEpollServer::StopWrite(int fd) { ModifyFD(fd, EPOLLOUT, 0); }
-
-void SimpleEpollServer::StartWrite(int fd) { ModifyFD(fd, 0, EPOLLOUT); }
-
-void SimpleEpollServer::HandleEvent(int fd, int event_mask) {
-#ifdef EPOLL_SERVER_EVENT_TRACING
-  event_recorder_.RecordEpollEvent(fd, event_mask);
-#endif
-  auto fd_i = cb_map_.find(CBAndEventMask(NULL, 0, fd));
-  if (fd_i == cb_map_.end() || fd_i->cb == NULL) {
-    // Ignore the event.
-    // This could occur if epoll() returns a set of events, and
-    // while processing event A (earlier) we removed the callback
-    // for event B (and are now processing event B).
-    return;
-  }
-  fd_i->events_asserted = event_mask;
-  CBAndEventMask* cb_and_mask = const_cast<CBAndEventMask*>(&*fd_i);
-  AddToReadyList(cb_and_mask);
-}
-
-void SimpleEpollServer::WaitForEventsAndExecuteCallbacks() {
-  if (in_wait_for_events_and_execute_callbacks_) {
-    EPOLL_LOG(DFATAL) << "Attempting to call WaitForEventsAndExecuteCallbacks"
-                         " when an ancestor to the current function is already"
-                         " WaitForEventsAndExecuteCallbacks!";
-    // The line below is actually tested, but in coverage mode,
-    // we never see it.
-    return;  // COV_NF_LINE
-  }
-  AutoReset<bool> recursion_guard(&in_wait_for_events_and_execute_callbacks_,
-                                  true);
-  if (alarm_map_.empty()) {
-    // no alarms, this is business as usual.
-    WaitForEventsAndCallHandleEvents(timeout_in_us_, events_, events_size_);
-    recorded_now_in_us_ = 0;
-    return;
-  }
-
-  // store the 'now'. If we recomputed 'now' every iteration
-  // down below, then we might never exit that loop-- any
-  // long-running alarms might install other long-running
-  // alarms, etc. By storing it here now, we ensure that
-  // a more reasonable amount of work is done here.
-  int64_t now_in_us = NowInUsec();
-
-  // Get the first timeout from the alarm_map where it is
-  // stored in absolute time.
-  int64_t next_alarm_time_in_us = alarm_map_.begin()->first;
-  EPOLL_VLOG(4) << "next_alarm_time = " << next_alarm_time_in_us
-                << " now             = " << now_in_us
-                << " timeout_in_us = " << timeout_in_us_;
-
-  int64_t wait_time_in_us;
-  int64_t alarm_timeout_in_us = next_alarm_time_in_us - now_in_us;
-
-  // If the next alarm is sooner than the default timeout, or if there is no
-  // timeout (timeout_in_us_ == -1), wake up when the alarm should fire.
-  // Otherwise use the default timeout.
-  if (alarm_timeout_in_us < timeout_in_us_ || timeout_in_us_ < 0) {
-    wait_time_in_us = std::max(alarm_timeout_in_us, static_cast<int64_t>(0));
-  } else {
-    wait_time_in_us = timeout_in_us_;
-  }
-
-  EPOLL_VLOG(4) << "wait_time_in_us = " << wait_time_in_us;
-
-  // wait for events.
-
-  WaitForEventsAndCallHandleEvents(wait_time_in_us, events_, events_size_);
-  CallAndReregisterAlarmEvents();
-  recorded_now_in_us_ = 0;
-}
-
-void SimpleEpollServer::SetFDReady(int fd, int events_to_fake) {
-  auto fd_i = cb_map_.find(CBAndEventMask(NULL, 0, fd));
-  if (cb_map_.end() != fd_i && fd_i->cb != NULL) {
-    // This const_cast is necessary for LIST_HEAD_INSERT to work. Declaring
-    // entry mutable is insufficient because LIST_HEAD_INSERT assigns the
-    // forward pointer of the list head to the current cb_and_mask, and the
-    // compiler complains that it can't assign a const T* to a T*.
-    CBAndEventMask* cb_and_mask = const_cast<CBAndEventMask*>(&*fd_i);
-    // Note that there is no clearly correct behavior here when
-    // cb_and_mask->events_to_fake != 0 and this function is called.
-    // Of the two operations:
-    //      cb_and_mask->events_to_fake = events_to_fake
-    //      cb_and_mask->events_to_fake |= events_to_fake
-    // the first was picked because it discourages users from calling
-    // SetFDReady repeatedly to build up the correct event set as it is more
-    // efficient to call SetFDReady once with the correct, final mask.
-    cb_and_mask->events_to_fake = events_to_fake;
-    AddToReadyList(cb_and_mask);
-  }
-}
-
-void SimpleEpollServer::SetFDNotReady(int fd) {
-  auto fd_i = cb_map_.find(CBAndEventMask(NULL, 0, fd));
-  if (cb_map_.end() != fd_i) {
-    RemoveFromReadyList(*fd_i);
-  }
-}
-
-bool SimpleEpollServer::IsFDReady(int fd) const {
-  auto fd_i = cb_map_.find(CBAndEventMask(NULL, 0, fd));
-  return (cb_map_.end() != fd_i && fd_i->cb != NULL &&
-          fd_i->entry.le_prev != NULL);
-}
-
-void SimpleEpollServer::VerifyReadyList() const {
-  int count = 0;
-  CBAndEventMask* cur = ready_list_.lh_first;
-  for (; cur; cur = cur->entry.le_next) {
-    ++count;
-  }
-  for (cur = tmp_list_.lh_first; cur; cur = cur->entry.le_next) {
-    ++count;
-  }
-  CHECK_EQ(ready_list_size_, count) << "Ready list size does not match count";
-}
-
-void SimpleEpollServer::RegisterAlarm(int64_t timeout_time_in_us, AlarmCB* ac) {
-  EPOLL_VLOG(4) << "RegisteringAlarm " << ac << " at : " << timeout_time_in_us;
-  CHECK(ac);
-  if (all_alarms_.find(ac) != all_alarms_.end()) {
-    EPOLL_BUG(epoll_bug_1_1) << "Alarm already exists";
-  }
-
-  auto alarm_iter = alarm_map_.insert(std::make_pair(timeout_time_in_us, ac));
-
-  all_alarms_.insert(ac);
-  // Pass the iterator to the EpollAlarmCallbackInterface.
-  ac->OnRegistration(alarm_iter, this);
-}
-
-// Unregister a specific alarm callback: iterator_token must be a
-//  valid iterator. The caller must ensure the validity of the iterator.
-void SimpleEpollServer::UnregisterAlarm(const AlarmRegToken& iterator_token) {
-  AlarmCB* cb = iterator_token->second;
-  EPOLL_VLOG(4) << "UnregisteringAlarm " << cb;
-  alarm_map_.erase(iterator_token);
-  all_alarms_.erase(cb);
-  cb->OnUnregistration();
-}
-
-SimpleEpollServer::AlarmRegToken SimpleEpollServer::ReregisterAlarm(
-    SimpleEpollServer::AlarmRegToken iterator_token,
-    int64_t timeout_time_in_us) {
-  AlarmCB* cb = iterator_token->second;
-  alarm_map_.erase(iterator_token);
-  return alarm_map_.emplace(timeout_time_in_us, cb);
-}
-
-int SimpleEpollServer::NumFDsRegistered() const {
-  DCHECK_GE(cb_map_.size(), 1u);
-  // Omit the internal FD (read_fd_)
-  return cb_map_.size() - 1;
-}
-
-void SimpleEpollServer::Wake() {
-  char data = 'd';  // 'd' is for data.  It's good enough for me.
-  int rv = write(write_fd_, &data, 1);
-  DCHECK_EQ(rv, 1);
-}
-
-int64_t SimpleEpollServer::NowInUsec() const {
-  return absl::GetCurrentTimeNanos() / 1000;
-}
-
-int64_t SimpleEpollServer::ApproximateNowInUsec() const {
-  if (recorded_now_in_us_ != 0) {
-    return recorded_now_in_us_;
-  }
-  return this->NowInUsec();
-}
-
-std::string SimpleEpollServer::EventMaskToString(int event_mask) {
-  std::string s;
-  if (event_mask & EPOLLIN) s += "EPOLLIN ";
-  if (event_mask & EPOLLPRI) s += "EPOLLPRI ";
-  if (event_mask & EPOLLOUT) s += "EPOLLOUT ";
-  if (event_mask & EPOLLRDNORM) s += "EPOLLRDNORM ";
-  if (event_mask & EPOLLRDBAND) s += "EPOLLRDBAND ";
-  if (event_mask & EPOLLWRNORM) s += "EPOLLWRNORM ";
-  if (event_mask & EPOLLWRBAND) s += "EPOLLWRBAND ";
-  if (event_mask & EPOLLMSG) s += "EPOLLMSG ";
-  if (event_mask & EPOLLERR) s += "EPOLLERR ";
-  if (event_mask & EPOLLHUP) s += "EPOLLHUP ";
-  if (event_mask & EPOLLONESHOT) s += "EPOLLONESHOT ";
-  if (event_mask & EPOLLET) s += "EPOLLET ";
-  return s;
-}
-
-void SimpleEpollServer::LogStateOnCrash() {
-  EPOLL_LOG(ERROR)
-      << "-------------------Epoll Server-------------------------";
-  EPOLL_LOG(ERROR) << "Epoll server " << this << " polling on fd " << epoll_fd_;
-  EPOLL_LOG(ERROR) << "timeout_in_us_: " << timeout_in_us_;
-
-  // Log sessions with alarms.
-  EPOLL_LOG(ERROR) << alarm_map_.size() << " alarms registered.";
-  for (auto it = alarm_map_.begin(); it != alarm_map_.end(); ++it) {
-    const bool skipped =
-        alarms_reregistered_and_should_be_skipped_.find(it->second) !=
-        alarms_reregistered_and_should_be_skipped_.end();
-    EPOLL_LOG(ERROR) << "Alarm " << it->second << " registered at time "
-                     << it->first << " and should be skipped = " << skipped;
-  }
-
-  EPOLL_LOG(ERROR) << cb_map_.size() << " fd callbacks registered.";
-  for (auto it = cb_map_.begin(); it != cb_map_.end(); ++it) {
-    EPOLL_LOG(ERROR) << "fd: " << it->fd << " with mask " << it->event_mask
-                     << " registered with cb: " << it->cb;
-  }
-  EPOLL_LOG(ERROR)
-      << "-------------------/Epoll Server------------------------";
-}
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-
-void SimpleEpollServer::DelFD(int fd) const {
-  struct epoll_event ee;
-  memset(&ee, 0, sizeof(ee));
-#ifdef EPOLL_SERVER_EVENT_TRACING
-  event_recorder_.RecordFDMaskEvent(fd, 0, "DelFD");
-#endif
-  if (epoll_ctl(epoll_fd_, EPOLL_CTL_DEL, fd, &ee)) {
-    int saved_errno = errno;
-    char buf[kErrorBufferSize];
-    EPOLL_LOG(FATAL) << "Epoll set removal error for fd " << fd << ": "
-                     << strerror_r(saved_errno, buf, sizeof(buf));
-  }
-}
-
-////////////////////////////////////////
-
-void SimpleEpollServer::AddFD(int fd, int event_mask) const {
-  struct epoll_event ee;
-  memset(&ee, 0, sizeof(ee));
-  ee.events = event_mask | EPOLLERR | EPOLLHUP;
-  ee.data.fd = fd;
-#ifdef EPOLL_SERVER_EVENT_TRACING
-  event_recorder_.RecordFDMaskEvent(fd, ee.events, "AddFD");
-#endif
-  if (epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, fd, &ee)) {
-    int saved_errno = errno;
-    char buf[kErrorBufferSize];
-    EPOLL_LOG(FATAL) << "Epoll set insertion error for fd " << fd << ": "
-                     << strerror_r(saved_errno, buf, sizeof(buf));
-  }
-}
-
-////////////////////////////////////////
-
-void SimpleEpollServer::ModFD(int fd, int event_mask) const {
-  struct epoll_event ee;
-  memset(&ee, 0, sizeof(ee));
-  ee.events = event_mask | EPOLLERR | EPOLLHUP;
-  ee.data.fd = fd;
-#ifdef EPOLL_SERVER_EVENT_TRACING
-  event_recorder_.RecordFDMaskEvent(fd, ee.events, "ModFD");
-#endif
-  EPOLL_VLOG(3) << "modifying fd= " << fd << " "
-                << EventMaskToString(ee.events);
-  if (epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, fd, &ee)) {
-    int saved_errno = errno;
-    char buf[kErrorBufferSize];
-    EPOLL_LOG(FATAL) << "Epoll set modification error for fd " << fd << ": "
-                     << strerror_r(saved_errno, buf, sizeof(buf));
-  }
-}
-
-////////////////////////////////////////
-
-void SimpleEpollServer::ModifyFD(int fd, int remove_event, int add_event) {
-  auto fd_i = cb_map_.find(CBAndEventMask(NULL, 0, fd));
-  if (cb_map_.end() == fd_i) {
-    EPOLL_VLOG(2) << "Didn't find the fd " << fd << "in internal structures";
-    return;
-  }
-
-  if (fd_i->cb != NULL) {
-    int& event_mask = fd_i->event_mask;
-    EPOLL_VLOG(3) << "fd= " << fd
-                  << " event_mask before: " << EventMaskToString(event_mask);
-    event_mask &= ~remove_event;
-    event_mask |= add_event;
-
-    EPOLL_VLOG(3) << " event_mask after: " << EventMaskToString(event_mask);
-
-    ModFD(fd, event_mask);
-
-    fd_i->cb->OnModification(fd, event_mask);
-  }
-}
-
-void SimpleEpollServer::WaitForEventsAndCallHandleEvents(
-    int64_t timeout_in_us, struct epoll_event events[], int events_size) {
-  if (timeout_in_us == 0 || ready_list_.lh_first != NULL) {
-    // If ready list is not empty, then don't sleep at all.
-    timeout_in_us = 0;
-  } else if (timeout_in_us < 0) {
-    EPOLL_LOG(INFO) << "Negative epoll timeout: " << timeout_in_us
-                    << "us; epoll will wait forever for events.";
-    // If timeout_in_us is < 0 we are supposed to Wait forever.  This means we
-    // should set timeout_in_us to -1000 so we will
-    // Wait(-1000/1000) == Wait(-1) == Wait forever.
-    timeout_in_us = -1000;
-  } else {
-    // If timeout is specified, and the ready list is empty.
-    if (timeout_in_us < 1000) {
-      timeout_in_us = 1000;
-    }
-  }
-  const int timeout_in_ms = timeout_in_us / 1000;
-  int64_t expected_wakeup_us = NowInUsec() + timeout_in_us;
-
-  int nfds = epoll_wait_impl(epoll_fd_, events, events_size, timeout_in_ms);
-  EPOLL_VLOG(3) << "nfds=" << nfds;
-
-#ifdef EPOLL_SERVER_EVENT_TRACING
-  event_recorder_.RecordEpollWaitEvent(timeout_in_ms, nfds);
-#endif
-
-  // If you're wondering why the NowInUsec() is recorded here, the answer is
-  // simple: If we did it before the epoll_wait_impl, then the max error for
-  // the ApproximateNowInUs() call would be as large as the maximum length of
-  // epoll_wait, which can be arbitrarily long. Since this would make
-  // ApproximateNowInUs() worthless, we instead record the time -after- we've
-  // done epoll_wait, which guarantees that the maximum error is the amount of
-  // time it takes to process all the events generated by epoll_wait.
-  recorded_now_in_us_ = NowInUsec();
-
-  if (timeout_in_us > 0) {
-    int64_t delta = NowInUsec() - expected_wakeup_us;
-    last_delay_in_usec_ = delta > 0 ? delta : 0;
-  } else {
-    // timeout_in_us < 0 means we waited forever until an event;
-    // timeout_in_us == 0 means there was no kernel delay to track.
-    last_delay_in_usec_ = 0;
-  }
-
-  if (nfds > 0) {
-    for (int i = 0; i < nfds; ++i) {
-      int event_mask = events[i].events;
-      int fd = events[i].data.fd;
-      HandleEvent(fd, event_mask);
-    }
-  } else if (nfds < 0) {
-    // Catch interrupted syscall and just ignore it and move on.
-    if (errno != EINTR && errno != 0) {
-      int saved_errno = errno;
-      char buf[kErrorBufferSize];
-      EPOLL_LOG(FATAL) << "Error " << saved_errno << " in epoll_wait: "
-                       << strerror_r(saved_errno, buf, sizeof(buf));
-    }
-  }
-
-  // Now run through the ready list.
-  if (ready_list_.lh_first) {
-    CallReadyListCallbacks();
-  }
-}
-
-void SimpleEpollServer::CallReadyListCallbacks() {
-  // Check pre-conditions.
-  DCHECK(tmp_list_.lh_first == NULL);
-  // Swap out the ready_list_ into the tmp_list_ before traversing the list to
-  // enable SetFDReady() to just push new items into the ready_list_.
-  std::swap(ready_list_.lh_first, tmp_list_.lh_first);
-  if (tmp_list_.lh_first) {
-    tmp_list_.lh_first->entry.le_prev = &tmp_list_.lh_first;
-    EpollEvent event(0);
-    while (tmp_list_.lh_first != NULL) {
-      DCHECK_GT(ready_list_size_, 0);
-      CBAndEventMask* cb_and_mask = tmp_list_.lh_first;
-      RemoveFromReadyList(*cb_and_mask);
-
-      event.out_ready_mask = 0;
-      event.in_events =
-          cb_and_mask->events_asserted | cb_and_mask->events_to_fake;
-      // TODO(fenix): get rid of the two separate fields in cb_and_mask.
-      cb_and_mask->events_asserted = 0;
-      cb_and_mask->events_to_fake = 0;
-      {
-        // OnEvent() may call UnRegister, so we set in_use, here. Any
-        // UnRegister call will now simply set the cb to NULL instead of
-        // invalidating the cb_and_mask object (by deleting the object in the
-        // map to which cb_and_mask refers)
-        AutoReset<bool> in_use_guard(&(cb_and_mask->in_use), true);
-        cb_and_mask->cb->OnEvent(cb_and_mask->fd, &event);
-      }
-
-      // Since OnEvent may have called UnregisterFD, we must check here that
-      // the callback is still valid. If it isn't, then UnregisterFD *was*
-      // called, and we should now get rid of the object.
-      if (cb_and_mask->cb == NULL) {
-        cb_map_.erase(*cb_and_mask);
-      } else if (event.out_ready_mask != 0) {
-        cb_and_mask->events_to_fake = event.out_ready_mask;
-        AddToReadyList(cb_and_mask);
-      }
-    }
-  }
-  DCHECK(tmp_list_.lh_first == NULL);
-}
-
-void SimpleEpollServer::CallAndReregisterAlarmEvents() {
-  int64_t now_in_us = recorded_now_in_us_;
-  DCHECK_NE(0, recorded_now_in_us_);
-
-  TimeToAlarmCBMap::iterator erase_it;
-
-  // execute alarms.
-  for (auto i = alarm_map_.begin(); i != alarm_map_.end();) {
-    if (i->first > now_in_us) {
-      break;
-    }
-    AlarmCB* cb = i->second;
-    // Execute the OnAlarm() only if we did not register
-    // it in this loop itself.
-    const bool added_in_this_round =
-        alarms_reregistered_and_should_be_skipped_.find(cb) !=
-        alarms_reregistered_and_should_be_skipped_.end();
-    if (added_in_this_round) {
-      ++i;
-      continue;
-    }
-    all_alarms_.erase(cb);
-    const int64_t new_timeout_time_in_us = cb->OnAlarm();
-
-    erase_it = i;
-    ++i;
-    alarm_map_.erase(erase_it);
-
-    if (new_timeout_time_in_us > 0) {
-      // We add to hash_set only if the new timeout is <= now_in_us.
-      // if timeout is > now_in_us then we have no fear that this alarm
-      // can be reexecuted in this loop, and hence we do not need to
-      // worry about a recursive loop.
-      EPOLL_DVLOG(3) << "Reregistering alarm "
-                     << " " << cb << " " << new_timeout_time_in_us << " "
-                     << now_in_us;
-      if (new_timeout_time_in_us <= now_in_us) {
-        alarms_reregistered_and_should_be_skipped_.insert(cb);
-      }
-      RegisterAlarm(new_timeout_time_in_us, cb);
-    }
-  }
-  alarms_reregistered_and_should_be_skipped_.clear();
-}
-
-EpollAlarm::EpollAlarm() : eps_(NULL), registered_(false) {}
-
-EpollAlarm::~EpollAlarm() { UnregisterIfRegistered(); }
-
-int64_t EpollAlarm::OnAlarm() {
-  registered_ = false;
-  return 0;
-}
-
-void EpollAlarm::OnRegistration(const SimpleEpollServer::AlarmRegToken& token,
-                                SimpleEpollServer* eps) {
-  DCHECK_EQ(false, registered_);
-
-  token_ = token;
-  eps_ = eps;
-  registered_ = true;
-}
-
-void EpollAlarm::OnUnregistration() { registered_ = false; }
-
-void EpollAlarm::OnShutdown(SimpleEpollServer* /*eps*/) {
-  registered_ = false;
-  eps_ = NULL;
-}
-
-// If the alarm was registered, unregister it.
-void EpollAlarm::UnregisterIfRegistered() {
-  if (!registered_) {
-    return;
-  }
-
-  eps_->UnregisterAlarm(token_);
-}
-
-void EpollAlarm::ReregisterAlarm(int64_t timeout_time_in_us) {
-  DCHECK(registered_);
-  token_ = eps_->ReregisterAlarm(token_, timeout_time_in_us);
-}
-
-}  // namespace epoll_server
diff --git a/quiche/epoll_server/simple_epoll_server.h b/quiche/epoll_server/simple_epoll_server.h
deleted file mode 100644
index 405e306..0000000
--- a/quiche/epoll_server/simple_epoll_server.h
+++ /dev/null
@@ -1,1051 +0,0 @@
-// 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_EPOLL_SERVER_SIMPLE_EPOLL_SERVER_H_
-#define QUICHE_EPOLL_SERVER_SIMPLE_EPOLL_SERVER_H_
-
-#include <fcntl.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <sys/queue.h>
-
-#include <map>
-#include <memory>
-#include <string>
-#include <unordered_map>
-#include <unordered_set>
-#include <vector>
-
-// #define EPOLL_SERVER_EVENT_TRACING 1
-//
-// Defining EPOLL_SERVER_EVENT_TRACING
-// causes code to exist which didn't before.
-// This code tracks each event generated by the epollserver,
-// as well as providing a per-fd-registered summary of
-// events. Note that enabling this code vastly slows
-// down operations, and uses substantially more
-// memory. For these reasons, it should only be enabled by developers doing
-// development at their workstations.
-//
-// A structure called 'EventRecorder' will exist when
-// the macro is defined. See the EventRecorder class interface
-// within the SimpleEpollServer class for more details.
-#ifdef EPOLL_SERVER_EVENT_TRACING
-#include <ostream>
-#endif
-
-#include <sys/epoll.h>
-
-#include "quiche/epoll_server/platform/api/epoll_logging.h"
-
-namespace epoll_server {
-
-class SimpleEpollServer;
-class EpollAlarmCallbackInterface;
-class ReadPipeCallback;
-
-struct EpollEvent {
-  EpollEvent(int events) : in_events(events), out_ready_mask(0) {}
-
-  int in_events;       // incoming events
-  int out_ready_mask;  // the new event mask for ready list (0 means don't
-                       // get on the ready list). This field is always
-                       // initialized to 0 when the event is passed to
-                       // OnEvent.
-};
-
-// Callbacks which go into SimpleEpollServers are expected to derive from this
-// class.
-class EpollCallbackInterface {
- public:
-  // Summary:
-  //   Called when the callback is registered into a SimpleEpollServer.
-  // Args:
-  //   eps - the poll server into which this callback was registered
-  //   fd - the file descriptor which was registered
-  //   event_mask - the event mask (composed of EPOLLIN, EPOLLOUT, etc)
-  //                which was registered (and will initially be used
-  //                in the epoll() calls)
-  virtual void OnRegistration(SimpleEpollServer* eps, int fd,
-                              int event_mask) = 0;
-
-  // Summary:
-  //   Called when the event_mask is modified (for a file-descriptor)
-  // Args:
-  //   fd - the file descriptor which was registered
-  //   event_mask - the event mask (composed of EPOLLIN, EPOLLOUT, etc)
-  //                which was is now curren (and will be used
-  //                in subsequent epoll() calls)
-  virtual void OnModification(int fd, int event_mask) = 0;
-
-  // Summary:
-  //   Called whenever an event occurs on the file-descriptor.
-  //   This is where the bulk of processing is expected to occur.
-  // Args:
-  //   fd - the file descriptor which was registered
-  //   event - a struct that contains the event mask (composed of EPOLLIN,
-  //           EPOLLOUT, etc), a flag that indicates whether this is a true
-  //           epoll_wait event vs one from the ready list, and an output
-  //           parameter for OnEvent to inform the SimpleEpollServer whether to
-  //           put this fd on the ready list.
-  virtual void OnEvent(int fd, EpollEvent* event) = 0;
-
-  // Summary:
-  //   Called when the file-descriptor is unregistered from the poll-server.
-  // Args:
-  //   fd - the file descriptor which was registered, and of this call, is now
-  //        unregistered.
-  //   replaced - If true, this callback is being replaced by another, otherwise
-  //              it is simply being removed.
-  virtual void OnUnregistration(int fd, bool replaced) = 0;
-
-  // Summary:
-  //   Called when the epoll server is shutting down.  This is different from
-  //   OnUnregistration because the subclass may want to clean up memory.
-  //   This is called in leiu of OnUnregistration.
-  // Args:
-  //  fd - the file descriptor which was registered.
-  virtual void OnShutdown(SimpleEpollServer* eps, int fd) = 0;
-
-  // Summary:
-  //   Returns a name describing the class for use in debug/error reporting.
-  virtual std::string Name() const = 0;
-
-  virtual ~EpollCallbackInterface() {}
-
- protected:
-  EpollCallbackInterface() {}
-};
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-
-class SimpleEpollServer {
- public:
-  typedef EpollAlarmCallbackInterface AlarmCB;
-  typedef EpollCallbackInterface CB;
-
-  typedef std::multimap<int64_t, AlarmCB*> TimeToAlarmCBMap;
-  typedef TimeToAlarmCBMap::iterator AlarmRegToken;
-
-  // Summary:
-  //   Constructor:
-  //    By default, we don't wait any amount of time for events, and
-  //    we suggest to the epoll-system that we're going to use on-the-order
-  //    of 1024 FDs.
-  SimpleEpollServer();
-
-  SimpleEpollServer(const SimpleEpollServer&) = delete;
-  SimpleEpollServer operator=(const SimpleEpollServer&) = delete;
-
-  ////////////////////////////////////////
-
-  // Destructor
-  virtual ~SimpleEpollServer();
-
-  ////////////////////////////////////////
-
-  // Summary
-  //   Register a callback to be called whenever an event contained
-  //   in the set of events included in event_mask occurs on the
-  //   file-descriptor 'fd'
-  //
-  //   Note that only one callback is allowed to be registered for
-  //   any specific file-decriptor.
-  //
-  //   If a callback is registered for a file-descriptor which has already
-  //   been registered, then the previous callback is unregistered with
-  //   the 'replaced' flag set to true. I.e. the previous callback's
-  //   OnUnregistration() function is called like so:
-  //      OnUnregistration(fd, true);
-  //
-  //  The epoll server does NOT take on ownership of the callback: the callback
-  //  creator is responsible for managing that memory.
-  //
-  // Args:
-  //   fd - a valid file-descriptor
-  //   cb - an instance of a subclass of EpollCallbackInterface
-  //   event_mask - a combination of (EPOLLOUT, EPOLLIN.. etc) indicating
-  //                the events for which the callback would like to be
-  //                called.
-  virtual void RegisterFD(int fd, CB* cb, int event_mask);
-
-  ////////////////////////////////////////
-
-  // Summary:
-  //   A shortcut for RegisterFD which sets things up such that the
-  //   callback is called when 'fd' is available for writing.
-  // Args:
-  //   fd - a valid file-descriptor
-  //   cb - an instance of a subclass of EpollCallbackInterface
-  virtual void RegisterFDForWrite(int fd, CB* cb);
-
-  ////////////////////////////////////////
-
-  // Summary:
-  //   A shortcut for RegisterFD which sets things up such that the
-  //   callback is called when 'fd' is available for reading or writing.
-  // Args:
-  //   fd - a valid file-descriptor
-  //   cb - an instance of a subclass of EpollCallbackInterface
-  virtual void RegisterFDForReadWrite(int fd, CB* cb);
-
-  ////////////////////////////////////////
-
-  // Summary:
-  //   A shortcut for RegisterFD which sets things up such that the
-  //   callback is called when 'fd' is available for reading.
-  // Args:
-  //   fd - a valid file-descriptor
-  //   cb - an instance of a subclass of EpollCallbackInterface
-  virtual void RegisterFDForRead(int fd, CB* cb);
-
-  ////////////////////////////////////////
-
-  // Summary:
-  //   Removes the FD and the associated callback from the pollserver.
-  //   If the callback is registered with other FDs, they will continue
-  //   to be processed using the callback without modification.
-  //   If the file-descriptor specified is not registered in the
-  //   epoll_server, then nothing happens as a result of this call.
-  // Args:
-  //   fd - the file-descriptor which should no-longer be monitored.
-  virtual void UnregisterFD(int fd);
-
-  ////////////////////////////////////////
-
-  // Summary:
-  //   Modifies the event mask for the file-descriptor, replacing
-  //   the old event_mask with the new one specified here.
-  //   If the file-descriptor specified is not registered in the
-  //   epoll_server, then nothing happens as a result of this call.
-  // Args:
-  //   fd - the fd whose event mask should be modified.
-  //   event_mask - the new event mask.
-  virtual void ModifyCallback(int fd, int event_mask);
-
-  ////////////////////////////////////////
-
-  // Summary:
-  //   Modifies the event mask for the file-descriptor such that we
-  //   no longer request events when 'fd' is readable.
-  //   If the file-descriptor specified is not registered in the
-  //   epoll_server, then nothing happens as a result of this call.
-  // Args:
-  //   fd - the fd whose event mask should be modified.
-  virtual void StopRead(int fd);
-
-  ////////////////////////////////////////
-
-  // Summary:
-  //   Modifies the event mask for the file-descriptor such that we
-  //   request events when 'fd' is readable.
-  //   If the file-descriptor specified is not registered in the
-  //   epoll_server, then nothing happens as a result of this call.
-  // Args:
-  //   fd - the fd whose event mask should be modified.
-  virtual void StartRead(int fd);
-
-  ////////////////////////////////////////
-
-  // Summary:
-  //   Modifies the event mask for the file-descriptor such that we
-  //   no longer request events when 'fd' is writable.
-  //   If the file-descriptor specified is not registered in the
-  //   epoll_server, then nothing happens as a result of this call.
-  // Args:
-  //   fd - the fd whose event mask should be modified.
-  virtual void StopWrite(int fd);
-
-  ////////////////////////////////////////
-
-  // Summary:
-  //   Modifies the event mask for the file-descriptor such that we
-  //   request events when 'fd' is writable.
-  //   If the file-descriptor specified is not registered in the
-  //   epoll_server, then nothing happens as a result of this call.
-  // Args:
-  //   fd - the fd whose event mask should be modified.
-  virtual void StartWrite(int fd);
-
-  ////////////////////////////////////////
-
-  // Summary:
-  //   Looks up the callback associated with the file-descriptor 'fd'.
-  //   If a callback is associated with this file-descriptor, then
-  //   it's OnEvent() method is called with the file-descriptor 'fd',
-  //   and event_mask 'event_mask'
-  //
-  //   If no callback is registered for this file-descriptor, nothing
-  //   will happen as a result of this call.
-  //
-  //   This function is used internally by the SimpleEpollServer, but is
-  //   available publicly so that events might be 'faked'. Calling
-  //   this function with an fd and event_mask is equivalent (as far
-  //   as the callback is concerned) to having a real event generated
-  //   by epoll (except, of course, that read(), etc won't necessarily
-  //   be able to read anything)
-  // Args:
-  //   fd - the file-descriptor on which an event has occurred.
-  //   event_mask - a bitmask representing the events which have occurred
-  //                on/for this fd. This bitmask is composed of
-  //                POLLIN, POLLOUT, etc.
-  //
-  void HandleEvent(int fd, int event_mask);
-
-  // Summary:
-  //   Call this when you want the pollserver to
-  //   wait for events and execute the callbacks associated with
-  //   the file-descriptors on which those events have occurred.
-  //   Depending on the value of timeout_in_us_, this may or may
-  //   not return immediately. Please reference the set_timeout()
-  //   function for the specific behaviour.
-  virtual void WaitForEventsAndExecuteCallbacks();
-
-  // Summary:
-  //   When an fd is registered to use edge trigger notification, the ready
-  //   list can be used to simulate level trigger semantics. Edge trigger
-  //   registration doesn't send an initial event, and only rising edge (going
-  //   from blocked to unblocked) events are sent. A callback can put itself on
-  //   the ready list by calling SetFDReady() after calling RegisterFD(). The
-  //   OnEvent method of all callbacks associated with the fds on the ready
-  //   list will be called immediately after processing the events returned by
-  //   epoll_wait(). The fd is removed from the ready list before the
-  //   callback's OnEvent() method is invoked. To stay on the ready list, the
-  //   OnEvent() (or some function in that call chain) must call SetFDReady
-  //   again. When a fd is unregistered using UnregisterFD(), the fd is
-  //   automatically removed from the ready list.
-  //
-  //   When the callback for a edge triggered fd hits the falling edge (about
-  //   to block, either because of it got an EAGAIN, or had a short read/write
-  //   operation), it should remove itself from the ready list using
-  //   SetFDNotReady() (since OnEvent cannot distinguish between invocation
-  //   from the ready list vs from a normal epoll event). All four ready list
-  //   methods are safe to be called  within the context of the callbacks.
-  //
-  //   Since the ready list invokes EpollCallbackInterface::OnEvent, only fds
-  //   that are registered with the SimpleEpollServer will be put on the ready
-  //   list. SetFDReady() and SetFDNotReady() will do nothing if the
-  //   SimpleEpollServer doesn't know about the fd passed in.
-  //
-  //   Since the ready list cannot reliably determine proper set of events
-  //   which should be sent to the callback, SetFDReady() requests the caller
-  //   to provide the ready list with the event mask, which will be used later
-  //   when OnEvent() is invoked by the ready list. Hence, the event_mask
-  //   passedto SetFDReady() does not affect the actual epoll registration of
-  //   the fd with the kernel. If a fd is already put on the ready list, and
-  //   SetFDReady() is called again for that fd with a different event_mask,
-  //   the event_mask will be updated.
-  virtual void SetFDReady(int fd, int events_to_fake);
-
-  virtual void SetFDNotReady(int fd);
-
-  // Summary:
-  //   IsFDReady(), ReadyListSize(), and VerifyReadyList are intended as
-  //   debugging tools and for writing unit tests.
-  //   ISFDReady() returns whether a fd is in the ready list.
-  //   ReadyListSize() returns the number of fds on the ready list.
-  //   VerifyReadyList() checks the consistency of internal data structure. It
-  //   will CHECK if it finds an error.
-  virtual bool IsFDReady(int fd) const;
-
-  size_t ReadyListSize() const { return ready_list_size_; }
-
-  void VerifyReadyList() const;
-
-  ////////////////////////////////////////
-
-  // Summary:
-  //   Registers an alarm 'ac' to go off at time 'timeout_time_in_us'.
-  //   If the callback returns a positive number from its OnAlarm() function,
-  //   then the callback will be re-registered at that time, else the alarm
-  //   owner is responsible for freeing up memory.
-  //
-  //   Important: A give AlarmCB* can not be registered again if it is already
-  //    registered. If a user wants to register a callback again it should first
-  //    unregister the previous callback before calling RegisterAlarm again.
-  // Args:
-  //   timeout_time_in_us - the absolute time at which the alarm should go off
-  //   ac - the alarm which will be called.
-  virtual void RegisterAlarm(int64_t timeout_time_in_us, AlarmCB* ac);
-
-  // Summary:
-  //   Registers an alarm 'ac' to go off at time: (ApproximateNowInUs() +
-  //   delta_in_us). While this is somewhat less accurate (see the description
-  //   for ApproximateNowInUs() to see how 'approximate'), the error is never
-  //   worse than the amount of time it takes to process all events in one
-  //   WaitForEvents.  As with 'RegisterAlarm()', if the callback returns a
-  //   positive number from its OnAlarm() function, then the callback will be
-  //   re-registered at that time, else the alarm owner is responsible for
-  //   freeing up memory.
-  //   Note that this function is purely a convienence. The
-  //   same thing may be accomplished by using RegisterAlarm with
-  //   ApproximateNowInUs() directly.
-  //
-  //   Important: A give AlarmCB* can not be registered again if it is already
-  //    registered. If a user wants to register a callback again it should first
-  //    unregister the previous callback before calling RegisterAlarm again.
-  // Args:
-  //   delta_in_us - the delta in microseconds from the ApproximateTimeInUs() at
-  //                 which point the alarm should go off.
-  //   ac - the alarm which will be called.
-  void RegisterAlarmApproximateDelta(int64_t delta_in_us, AlarmCB* ac) {
-    RegisterAlarm(ApproximateNowInUsec() + delta_in_us, ac);
-  }
-
-  ////////////////////////////////////////
-
-  // Summary:
-  //   Unregister  the alarm referred to by iterator_token; Callers should
-  //   be warned that a token may have become already invalid when OnAlarm()
-  //   is called, was unregistered, or OnShutdown was called on that alarm.
-  // Args:
-  //    iterator_token - iterator to the alarm callback to unregister.
-  virtual void UnregisterAlarm(
-      const SimpleEpollServer::AlarmRegToken& iterator_token);
-
-  virtual SimpleEpollServer::AlarmRegToken ReregisterAlarm(
-      SimpleEpollServer::AlarmRegToken iterator_token,
-      int64_t timeout_time_in_us);
-
-  ////////////////////////////////////////
-
-  // Summary:
-  //   returns the number of file-descriptors registered in this
-  //   SimpleEpollServer.
-  // Returns:
-  //   number of FDs registered (discounting the internal pipe used for Wake)
-  virtual int NumFDsRegistered() const;
-
-  // Summary:
-  //   Force the epoll server to wake up (by writing to an internal pipe).
-  virtual void Wake();
-
-  // Summary:
-  //   Wrapper around WallTimer's NowInUsec.  We do this so that we can test
-  //   SimpleEpollServer without using the system clock (and can avoid the
-  //   flakiness that would ensue)
-  // Returns:
-  //   the current time as number of microseconds since the Unix epoch.
-  virtual int64_t NowInUsec() const;
-
-  // Summary:
-  //   Since calling NowInUsec() many thousands of times per
-  //   WaitForEventsAndExecuteCallbacks function call is, to say the least,
-  //   inefficient, we allow users to use an approximate time instead. The
-  //   time returned from this function is as accurate as NowInUsec() when
-  //   WaitForEventsAndExecuteCallbacks is not an ancestor of the caller's
-  //   callstack.
-  //   However, when WaitForEventsAndExecuteCallbacks -is- an ancestor, then
-  //   this function returns the time at which the
-  //   WaitForEventsAndExecuteCallbacks function started to process events or
-  //   alarms.
-  //
-  //   Essentially, this function makes available a fast and mostly accurate
-  //   mechanism for getting the time for any function handling an event or
-  //   alarm. When functions which are not handling callbacks or alarms call
-  //   this function, they get the slow and "absolutely" accurate time.
-  //
-  //   Users should be encouraged to use this function.
-  // Returns:
-  //   the "approximate" current time as number of microseconds since the Unix
-  //   epoch.
-  virtual int64_t ApproximateNowInUsec() const;
-
-  static std::string EventMaskToString(int event_mask);
-
-  // Summary:
-  //   Logs the state of the epoll server with EPOLL_LOG(ERROR).
-  void LogStateOnCrash();
-
-  // Summary:
-  //   Set the timeout to the value specified.
-  //   If the timeout is set to a negative number,
-  //      WaitForEventsAndExecuteCallbacks() will only return when an event has
-  //      occurred
-  //   If the timeout is set to zero,
-  //      WaitForEventsAndExecuteCallbacks() will return immediately
-  //   If the timeout is set to a positive number,
-  //      WaitForEventsAndExecuteCallbacks() will return when an event has
-  //      occurred, or when timeout_in_us microseconds has elapsed, whichever
-  //      is first.
-  //  Args:
-  //    timeout_in_us - value specified depending on behaviour desired.
-  //                    See above.
-  void set_timeout_in_us(int64_t timeout_in_us) {
-    timeout_in_us_ = timeout_in_us;
-  }
-
-  ////////////////////////////////////////
-
-  // Summary:
-  //   Accessor for the current value of timeout_in_us.
-  int timeout_in_us_for_test() const { return timeout_in_us_; }
-
-  // Summary:
-  // Returns true when the SimpleEpollServer() is being destroyed.
-  bool in_shutdown() const { return in_shutdown_; }
-  bool ShutdownCalled() const { return in_shutdown(); }
-
-  // Compatibility stub.
-  void Shutdown() {}
-
-  // Summary:
-  //   A function for implementing the ready list. It invokes OnEvent for each
-  //   of the fd in the ready list, and takes care of adding them back to the
-  //   ready list if the callback requests it (by checking that out_ready_mask
-  //   is non-zero).
-  void CallReadyListCallbacks();
-
-  int64_t LastDelayInUsec() const { return last_delay_in_usec_; }
-
- protected:
-  virtual void SetNonblocking(int fd);
-
-  // This exists here so that we can override this function in unittests
-  // in order to make effective mock SimpleEpollServer objects.
-  virtual int epoll_wait_impl(int epfd, struct epoll_event* events,
-                              int max_events, int timeout_in_ms);
-
-  // this struct is used internally, and is never used by anything external
-  // to this class. Some of its members are declared mutable to get around the
-  // restriction imposed by hash_set. Since hash_set knows nothing about the
-  // objects it stores, it has to assume that every bit of the object is used
-  // in the hash function and equal_to comparison. Thus hash_set::iterator is a
-  // const iterator. In this case, the only thing that must stay constant is
-  // fd. Everything else are just along for the ride and changing them doesn't
-  // compromise the hash_set integrity.
-  struct CBAndEventMask {
-    CBAndEventMask()
-        : cb(NULL),
-          fd(-1),
-          event_mask(0),
-          events_asserted(0),
-          events_to_fake(0),
-          in_use(false) {
-      entry.le_next = NULL;
-      entry.le_prev = NULL;
-    }
-
-    CBAndEventMask(EpollCallbackInterface* cb, int event_mask, int fd)
-        : cb(cb),
-          fd(fd),
-          event_mask(event_mask),
-          events_asserted(0),
-          events_to_fake(0),
-          in_use(false) {
-      entry.le_next = NULL;
-      entry.le_prev = NULL;
-    }
-
-    // Required operator for hash_set. Normally operator== should be a free
-    // standing function. However, since CBAndEventMask is a protected type and
-    // it will never be a base class, it makes no difference.
-    bool operator==(const CBAndEventMask& cb_and_mask) const {
-      return fd == cb_and_mask.fd;
-    }
-    // A callback. If the fd is unregistered inside the callchain of OnEvent,
-    // the cb will be set to NULL.
-    mutable EpollCallbackInterface* cb;
-
-    mutable LIST_ENTRY(CBAndEventMask) entry;
-    // file descriptor registered with the epoll server.
-    int fd;
-    // the current event_mask registered for this callback.
-    mutable int event_mask;
-    // the event_mask that was returned by epoll
-    mutable int events_asserted;
-    // the event_mask for the ready list to use to call OnEvent.
-    mutable int events_to_fake;
-    // toggle around calls to OnEvent to tell UnregisterFD to not erase the
-    // iterator because HandleEvent is using it.
-    mutable bool in_use;
-  };
-
-  // Custom hash function to be used by hash_set.
-  struct CBAndEventMaskHash {
-    size_t operator()(const CBAndEventMask& cb_and_eventmask) const {
-      return static_cast<size_t>(cb_and_eventmask.fd);
-    }
-  };
-
-  using FDToCBMap = std::unordered_set<CBAndEventMask, CBAndEventMaskHash>;
-
-  // the following four functions are OS-specific, and are likely
-  // to be changed in a subclass if the poll/select method is changed
-  // from epoll.
-
-  // Summary:
-  //   Deletes a file-descriptor from the set of FDs that should be
-  //   monitored with epoll.
-  //   Note that this only deals with modifying data relating -directly-
-  //   with the epoll call-- it does not modify any data within the
-  //   epoll_server.
-  // Args:
-  //   fd - the file descriptor to-be-removed from the monitoring set
-  virtual void DelFD(int fd) const;
-
-  ////////////////////////////////////////
-
-  // Summary:
-  //   Adds a file-descriptor to the set of FDs that should be
-  //   monitored with epoll.
-  //   Note that this only deals with modifying data relating -directly-
-  //   with the epoll call.
-  // Args:
-  //   fd - the file descriptor to-be-added to the monitoring set
-  //   event_mask - the event mask (consisting of EPOLLIN, EPOLLOUT, etc
-  //                 OR'd together) which will be associated with this
-  //                 FD initially.
-  virtual void AddFD(int fd, int event_mask) const;
-
-  ////////////////////////////////////////
-
-  // Summary:
-  //   Modifies a file-descriptor in the set of FDs that should be
-  //   monitored with epoll.
-  //   Note that this only deals with modifying data relating -directly-
-  //   with the epoll call.
-  // Args:
-  //   fd - the file descriptor to-be-added to the monitoring set
-  //   event_mask - the event mask (consisting of EPOLLIN, EPOLLOUT, etc
-  //                 OR'd together) which will be associated with this
-  //                 FD after this call.
-  virtual void ModFD(int fd, int event_mask) const;
-
-  ////////////////////////////////////////
-
-  // Summary:
-  //   Modified the event mask associated with an FD in the set of
-  //   data needed by epoll.
-  //   Events are removed before they are added, thus, if ~0 is put
-  //   in 'remove_event', whatever is put in 'add_event' will be
-  //   the new event mask.
-  //   If the file-descriptor specified is not registered in the
-  //   epoll_server, then nothing happens as a result of this call.
-  // Args:
-  //   fd - the file descriptor whose event mask is to be modified
-  //   remove_event - the events which are to be removed from the current
-  //                  event_mask
-  //   add_event - the events which are to be added to the current event_mask
-  //
-  //
-  virtual void ModifyFD(int fd, int remove_event, int add_event);
-
-  ////////////////////////////////////////
-
-  // Summary:
-  //   Waits for events, and calls HandleEvents() for each
-  //   fd, event pair discovered to possibly have an event.
-  //   Note that a callback (B) may get a spurious event if
-  //   another callback (A) has closed a file-descriptor N, and
-  //   the callback (B) has a newly opened file-descriptor, which
-  //   also happens to be N.
-  virtual void WaitForEventsAndCallHandleEvents(int64_t timeout_in_us,
-                                                struct epoll_event events[],
-                                                int events_size);
-
-  // Summary:
-  //   An internal function for implementing the ready list. It adds a fd's
-  //   CBAndEventMask to the ready list. If the fd is already on the ready
-  //   list, it is a no-op.
-  void AddToReadyList(CBAndEventMask* cb_and_mask);
-
-  // Summary:
-  //   An internal function for implementing the ready list. It remove a fd's
-  //   CBAndEventMask from the ready list. If the fd is not on the ready list,
-  //   it is a no-op.
-  void RemoveFromReadyList(const CBAndEventMask& cb_and_mask);
-
-  // Summary:
-  // Calls any pending alarms that should go off and reregisters them if they
-  // were recurring.
-  virtual void CallAndReregisterAlarmEvents();
-
-  // The file-descriptor created for epolling
-  int epoll_fd_;
-
-  // The mapping of file-descriptor to CBAndEventMasks
-  FDToCBMap cb_map_;
-
-  // Custom hash function to be used by hash_set.
-  struct AlarmCBHash {
-    size_t operator()(AlarmCB* const& p) const {
-      return reinterpret_cast<size_t>(p);
-    }
-  };
-
-  // TODO(sushantj): Having this hash_set is avoidable. We currently have it
-  // only so that we can enforce stringent checks that a caller can not register
-  // the same alarm twice. One option is to have an implementation in which
-  // this hash_set is used only in the debug mode.
-  using AlarmCBMap = std::unordered_set<AlarmCB*, AlarmCBHash>;
-  AlarmCBMap all_alarms_;
-
-  TimeToAlarmCBMap alarm_map_;
-
-  // The amount of time in microseconds that we'll wait before returning
-  // from the WaitForEventsAndExecuteCallbacks() function.
-  // If this is positive, wait that many microseconds.
-  // If this is negative, wait forever, or for the first event that occurs
-  // If this is zero, never wait for an event.
-  int64_t timeout_in_us_;
-
-  // This is nonzero only after the invocation of epoll_wait_impl within
-  // WaitForEventsAndCallHandleEvents and before the function
-  // WaitForEventsAndExecuteCallbacks returns.  At all other times, this is
-  // zero. This enables us to have relatively accurate time returned from the
-  // ApproximateNowInUs() function. See that function for more details.
-  int64_t recorded_now_in_us_;
-
-  // This is used to implement CallAndReregisterAlarmEvents. This stores
-  // all alarms that were reregistered because OnAlarm() returned a
-  // value > 0 and the time at which they should be executed is less that
-  // the current time.  By storing such alarms in this map we ensure
-  // that while calling CallAndReregisterAlarmEvents we do not call
-  // OnAlarm on any alarm in this set. This ensures that we do not
-  // go in an infinite loop.
-  AlarmCBMap alarms_reregistered_and_should_be_skipped_;
-
-  LIST_HEAD(ReadyList, CBAndEventMask) ready_list_;
-  LIST_HEAD(TmpList, CBAndEventMask) tmp_list_;
-  int ready_list_size_;
-  // TODO(alyssar): make this into something that scales up.
-  static const int events_size_ = 256;
-  struct epoll_event events_[256];
-
-#ifdef EPOLL_SERVER_EVENT_TRACING
-  struct EventRecorder {
-   public:
-    EventRecorder() : num_records_(0), record_threshold_(10000) {}
-
-    ~EventRecorder() { Clear(); }
-
-    // When a number of events equals the record threshold,
-    // the collected data summary for all FDs will be written
-    // to EPOLL_LOG(INFO). Note that this does not include the
-    // individual events (if you'reinterested in those, you'll
-    // have to get at them programmatically).
-    // After any such flushing to EPOLL_LOG(INFO) all events will
-    // be cleared.
-    // Note that the definition of an 'event' is a bit 'hazy',
-    // as it includes the 'Unregistration' event, and perhaps
-    // others.
-    void set_record_threshold(int64_t new_threshold) {
-      record_threshold_ = new_threshold;
-    }
-
-    void Clear() {
-      for (int i = 0; i < debug_events_.size(); ++i) {
-        delete debug_events_[i];
-      }
-      debug_events_.clear();
-      unregistered_fds_.clear();
-      event_counts_.clear();
-    }
-
-    void MaybeRecordAndClear() {
-      ++num_records_;
-      if ((num_records_ > record_threshold_) && (record_threshold_ > 0)) {
-        EPOLL_LOG(INFO) << "\n" << *this;
-        num_records_ = 0;
-        Clear();
-      }
-    }
-
-    void RecordFDMaskEvent(int fd, int mask, const char* function) {
-      FDMaskOutput* fdmo = new FDMaskOutput(fd, mask, function);
-      debug_events_.push_back(fdmo);
-      MaybeRecordAndClear();
-    }
-
-    void RecordEpollWaitEvent(int timeout_in_ms, int num_events_generated) {
-      EpollWaitOutput* ewo =
-          new EpollWaitOutput(timeout_in_ms, num_events_generated);
-      debug_events_.push_back(ewo);
-      MaybeRecordAndClear();
-    }
-
-    void RecordEpollEvent(int fd, int event_mask) {
-      Events& events_for_fd = event_counts_[fd];
-      events_for_fd.AssignFromMask(event_mask);
-      MaybeRecordAndClear();
-    }
-
-    friend ostream& operator<<(ostream& os, const EventRecorder& er) {
-      for (int i = 0; i < er.unregistered_fds_.size(); ++i) {
-        os << "fd: " << er.unregistered_fds_[i] << "\n";
-        os << er.unregistered_fds_[i];
-      }
-      for (EventCountsMap::const_iterator i = er.event_counts_.begin();
-           i != er.event_counts_.end(); ++i) {
-        os << "fd: " << i->first << "\n";
-        os << i->second;
-      }
-      for (int i = 0; i < er.debug_events_.size(); ++i) {
-        os << *(er.debug_events_[i]) << "\n";
-      }
-      return os;
-    }
-
-    void RecordUnregistration(int fd) {
-      EventCountsMap::iterator i = event_counts_.find(fd);
-      if (i != event_counts_.end()) {
-        unregistered_fds_.push_back(i->second);
-        event_counts_.erase(i);
-      }
-      MaybeRecordAndClear();
-    }
-
-   protected:
-    class DebugOutput {
-     public:
-      friend ostream& operator<<(ostream& os, const DebugOutput& debug_output) {
-        debug_output.OutputToStream(os);
-        return os;
-      }
-      virtual void OutputToStream(ostream* os) const = 0;
-      virtual ~DebugOutput() {}
-    };
-
-    class FDMaskOutput : public DebugOutput {
-     public:
-      FDMaskOutput(int fd, int mask, const char* function)
-          : fd_(fd), mask_(mask), function_(function) {}
-      virtual void OutputToStream(ostream* os) const {
-        (*os) << "func: " << function_ << "\tfd: " << fd_;
-        if (mask_ != 0) {
-          (*os) << "\tmask: " << EventMaskToString(mask_);
-        }
-      }
-      int fd_;
-      int mask_;
-      const char* function_;
-    };
-
-    class EpollWaitOutput : public DebugOutput {
-     public:
-      EpollWaitOutput(int timeout_in_ms, int num_events_generated)
-          : timeout_in_ms_(timeout_in_ms),
-            num_events_generated_(num_events_generated) {}
-      virtual void OutputToStream(ostream* os) const {
-        (*os) << "timeout_in_ms: " << timeout_in_ms_
-              << "\tnum_events_generated: " << num_events_generated_;
-      }
-
-     protected:
-      int timeout_in_ms_;
-      int num_events_generated_;
-    };
-
-    struct Events {
-      Events()
-          : epoll_in(0),
-            epoll_pri(0),
-            epoll_out(0),
-            epoll_rdnorm(0),
-            epoll_rdband(0),
-            epoll_wrnorm(0),
-            epoll_wrband(0),
-            epoll_msg(0),
-            epoll_err(0),
-            epoll_hup(0),
-            epoll_oneshot(0),
-            epoll_et(0) {}
-
-      void AssignFromMask(int event_mask) {
-        if (event_mask & EPOLLIN) ++epoll_in;
-        if (event_mask & EPOLLPRI) ++epoll_pri;
-        if (event_mask & EPOLLOUT) ++epoll_out;
-        if (event_mask & EPOLLRDNORM) ++epoll_rdnorm;
-        if (event_mask & EPOLLRDBAND) ++epoll_rdband;
-        if (event_mask & EPOLLWRNORM) ++epoll_wrnorm;
-        if (event_mask & EPOLLWRBAND) ++epoll_wrband;
-        if (event_mask & EPOLLMSG) ++epoll_msg;
-        if (event_mask & EPOLLERR) ++epoll_err;
-        if (event_mask & EPOLLHUP) ++epoll_hup;
-        if (event_mask & EPOLLONESHOT) ++epoll_oneshot;
-        if (event_mask & EPOLLET) ++epoll_et;
-      }
-
-      friend ostream& operator<<(ostream& os, const Events& ev) {
-        if (ev.epoll_in) {
-          os << "\t      EPOLLIN: " << ev.epoll_in << "\n";
-        }
-        if (ev.epoll_pri) {
-          os << "\t     EPOLLPRI: " << ev.epoll_pri << "\n";
-        }
-        if (ev.epoll_out) {
-          os << "\t     EPOLLOUT: " << ev.epoll_out << "\n";
-        }
-        if (ev.epoll_rdnorm) {
-          os << "\t  EPOLLRDNORM: " << ev.epoll_rdnorm << "\n";
-        }
-        if (ev.epoll_rdband) {
-          os << "\t  EPOLLRDBAND: " << ev.epoll_rdband << "\n";
-        }
-        if (ev.epoll_wrnorm) {
-          os << "\t  EPOLLWRNORM: " << ev.epoll_wrnorm << "\n";
-        }
-        if (ev.epoll_wrband) {
-          os << "\t  EPOLLWRBAND: " << ev.epoll_wrband << "\n";
-        }
-        if (ev.epoll_msg) {
-          os << "\t     EPOLLMSG: " << ev.epoll_msg << "\n";
-        }
-        if (ev.epoll_err) {
-          os << "\t     EPOLLERR: " << ev.epoll_err << "\n";
-        }
-        if (ev.epoll_hup) {
-          os << "\t     EPOLLHUP: " << ev.epoll_hup << "\n";
-        }
-        if (ev.epoll_oneshot) {
-          os << "\t EPOLLONESHOT: " << ev.epoll_oneshot << "\n";
-        }
-        if (ev.epoll_et) {
-          os << "\t      EPOLLET: " << ev.epoll_et << "\n";
-        }
-        return os;
-      }
-
-      unsigned int epoll_in;
-      unsigned int epoll_pri;
-      unsigned int epoll_out;
-      unsigned int epoll_rdnorm;
-      unsigned int epoll_rdband;
-      unsigned int epoll_wrnorm;
-      unsigned int epoll_wrband;
-      unsigned int epoll_msg;
-      unsigned int epoll_err;
-      unsigned int epoll_hup;
-      unsigned int epoll_oneshot;
-      unsigned int epoll_et;
-    };
-
-    std::vector<DebugOutput*> debug_events_;
-    std::vector<Events> unregistered_fds_;
-    using EventCountsMap = std::unordered_map<int, Events>;
-    EventCountsMap event_counts_;
-    int64_t num_records_;
-    int64_t record_threshold_;
-  };
-
-  void ClearEventRecords() { event_recorder_.Clear(); }
-  void WriteEventRecords(ostream* os) const { (*os) << event_recorder_; }
-
-  mutable EventRecorder event_recorder_;
-
-#endif
-
- private:
-  // Helper functions used in the destructor.
-  void CleanupFDToCBMap();
-  void CleanupTimeToAlarmCBMap();
-
-  // The callback registered to the fds below.  As the purpose of their
-  // registration is to wake the epoll server it just clears the pipe and
-  // returns.
-  std::unique_ptr<ReadPipeCallback> wake_cb_;
-
-  // A pipe owned by the epoll server.  The server will be registered to listen
-  // on read_fd_ and can be woken by Wake() which writes to write_fd_.
-  int read_fd_;
-  int write_fd_;
-
-  // This boolean is checked to see if it is false at the top of the
-  // WaitForEventsAndExecuteCallbacks function. If not, then it either returns
-  // without doing work, and logs to ERROR, or aborts the program (in
-  // DEBUG mode). If so, then it sets the bool to true, does work, and
-  // sets it back to false when done. This catches unwanted recursion.
-  bool in_wait_for_events_and_execute_callbacks_;
-
-  // Returns true when the SimpleEpollServer() is being destroyed.
-  bool in_shutdown_;
-  int64_t last_delay_in_usec_;
-};
-
-class EpollAlarmCallbackInterface {
- public:
-  // Summary:
-  //   Called when an alarm times out. Invalidates an AlarmRegToken.
-  //   WARNING: If a token was saved to refer to an alarm callback, OnAlarm must
-  //   delete it, as the reference is no longer valid.
-  // Returns:
-  //   the unix time (in microseconds) at which this alarm should be signaled
-  //   again, or 0 if the alarm should be removed.
-  virtual int64_t OnAlarm() = 0;
-
-  // Summary:
-  //   Called when the an alarm is registered. Invalidates an AlarmRegToken.
-  // Args:
-  //   token: the iterator to the alarm registered in the alarm map.
-  //   WARNING: this token becomes invalid when the alarm fires, is
-  //   unregistered, or OnShutdown is called on that alarm.
-  //   eps: the epoll server the alarm is registered with.
-  virtual void OnRegistration(const SimpleEpollServer::AlarmRegToken& token,
-                              SimpleEpollServer* eps) = 0;
-
-  // Summary:
-  //   Called when the an alarm is unregistered.
-  //   WARNING: It is not valid to unregister a callback and then use the token
-  //   that was saved to refer to the callback.
-  virtual void OnUnregistration() = 0;
-
-  // Summary:
-  //   Called when the epoll server is shutting down.
-  //   Invalidates the AlarmRegToken that was given when this alarm was
-  //   registered.
-  virtual void OnShutdown(SimpleEpollServer* eps) = 0;
-
-  virtual ~EpollAlarmCallbackInterface() {}
-
- protected:
-  EpollAlarmCallbackInterface() {}
-};
-
-// A simple alarm which unregisters itself on destruction.
-//
-// PLEASE NOTE:
-// Any classes overriding these functions must either call the implementation
-// of the parent class, or is must otherwise make sure that the 'registered_'
-// boolean and the token, 'token_', are updated appropriately.
-class EpollAlarm : public EpollAlarmCallbackInterface {
- public:
-  EpollAlarm();
-
-  ~EpollAlarm() override;
-
-  // Marks the alarm as unregistered and returns 0.  The return value may be
-  // safely ignored by subclasses.
-  int64_t OnAlarm() override;
-
-  // Marks the alarm as registered, and stores the token.
-  void OnRegistration(const SimpleEpollServer::AlarmRegToken& token,
-                      SimpleEpollServer* eps) override;
-
-  // Marks the alarm as unregistered.
-  void OnUnregistration() override;
-
-  // Marks the alarm as unregistered.
-  void OnShutdown(SimpleEpollServer* eps) override;
-
-  // If the alarm was registered, unregister it.
-  void UnregisterIfRegistered();
-
-  // Reregisters the alarm at specified time.
-  void ReregisterAlarm(int64_t timeout_time_in_us);
-
-  bool registered() const { return registered_; }
-
-  const SimpleEpollServer* eps() const { return eps_; }
-
- private:
-  SimpleEpollServer::AlarmRegToken token_;
-  SimpleEpollServer* eps_;
-  bool registered_;
-};
-
-}  // namespace epoll_server
-
-#endif  // QUICHE_EPOLL_SERVER_SIMPLE_EPOLL_SERVER_H_
diff --git a/quiche/epoll_server/simple_epoll_server_test.cc b/quiche/epoll_server/simple_epoll_server_test.cc
deleted file mode 100644
index ba85038..0000000
--- a/quiche/epoll_server/simple_epoll_server_test.cc
+++ /dev/null
@@ -1,2494 +0,0 @@
-// 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.
-
-// Epoll tests which determine that the right things happen in the right order.
-// Also lots of testing of individual functions.
-
-#include "quiche/epoll_server/simple_epoll_server.h"
-
-#include <errno.h>
-#include <fcntl.h>
-#include <netinet/in.h>
-#include <sys/epoll.h>
-#include <sys/socket.h>
-#include <unistd.h>
-
-#include <algorithm>
-#include <cstddef>
-#include <cstdlib>
-#include <cstring>
-#include <memory>
-#include <string>
-#include <unordered_map>
-#include <utility>
-#include <vector>
-
-#include "absl/time/clock.h"
-#include "quiche/epoll_server/fake_simple_epoll_server.h"
-#include "quiche/epoll_server/platform/api/epoll_address_test_utils.h"
-#include "quiche/epoll_server/platform/api/epoll_expect_bug.h"
-#include "quiche/epoll_server/platform/api/epoll_test.h"
-#include "quiche/epoll_server/platform/api/epoll_thread.h"
-
-namespace epoll_server {
-
-namespace test {
-
-namespace {
-
-const int kPageSize = 4096;
-const int kMaxBufLen = 10000;
-
-// These are used to record what is happening.
-enum {
-  CREATION,
-  REGISTRATION,
-  MODIFICATION,
-  EVENT,
-  UNREGISTRATION,
-  SHUTDOWN,
-  DESTRUCTION
-};
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-
-int64_t WallTimeNowInUsec() { return absl::GetCurrentTimeNanos() / 1000; }
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-
-struct RecordEntry {
-  RecordEntry() : time(0), instance(nullptr), event_type(0), fd(0), data(0) {}
-
-  RecordEntry(int64_t time, void* instance, int event_type, int fd, int data)
-      : time(time),
-        instance(instance),
-        event_type(event_type),
-        fd(fd),
-        data(data) {}
-
-  int64_t time;
-  void* instance;
-  int event_type;
-  int fd;
-  int data;
-
-  bool IsEqual(const RecordEntry* entry) const {
-    bool retval = true;
-
-    if (instance != entry->instance) {
-      retval = false;
-      EPOLL_LOG(INFO) << " instance (" << instance << ") != entry->instance("
-                      << entry->instance << ")";
-    }
-    if (event_type != entry->event_type) {
-      retval = false;
-      EPOLL_LOG(INFO) << " event_type (" << event_type
-                      << ") != entry->event_type(" << entry->event_type << ")";
-    }
-    if (fd != entry->fd) {
-      retval = false;
-      EPOLL_LOG(INFO) << " fd (" << fd << ") != entry->fd (" << entry->fd
-                      << ")";
-    }
-    if (data != entry->data) {
-      retval = false;
-      EPOLL_LOG(INFO) << " data (" << data << ") != entry->data(" << entry->data
-                      << ")";
-    }
-    return retval;
-  }
-};
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-
-class Recorder {
- public:
-  void Record(void* instance, int event_type, int fd, int data) {
-    records_.push_back(
-        RecordEntry(WallTimeNowInUsec(), instance, event_type, fd, data));
-  }
-
-  const std::vector<RecordEntry>* records() const { return &records_; }
-
-  bool IsEqual(const Recorder* recorder) const {
-    const std::vector<RecordEntry>* records = recorder->records();
-
-    if (records_.size() != records->size()) {
-      EPOLL_LOG(INFO) << "records_.size() (" << records_.size()
-                      << ") != records->size() (" << records->size() << ")";
-      return false;
-    }
-    for (size_t i = 0; i < std::min(records_.size(), records->size()); ++i) {
-      if (!records_[i].IsEqual(&(*records)[i])) {
-        EPOLL_LOG(INFO) << "entry in index: " << i << " differs from recorder.";
-        return false;
-      }
-    }
-    return true;
-  }
-
- private:
-  std::vector<RecordEntry> records_;
-};
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-
-class RecordingCB : public EpollCallbackInterface {
- public:
-  RecordingCB() : recorder_(new Recorder()) {
-    recorder_->Record(this, CREATION, 0, 0);
-  }
-
-  ~RecordingCB() override {
-    recorder_->Record(this, DESTRUCTION, 0, 0);
-    delete recorder_;
-  }
-
-  void OnRegistration(SimpleEpollServer* /*eps*/, int fd,
-                      int event_mask) override {
-    recorder_->Record(this, REGISTRATION, fd, event_mask);
-  }
-
-  void OnModification(int fd, int event_mask) override {
-    recorder_->Record(this, MODIFICATION, fd, event_mask);
-  }
-
-  void OnEvent(int fd, EpollEvent* event) override {
-    recorder_->Record(this, EVENT, fd, event->in_events);
-    if (event->in_events & EPOLLIN) {
-      const int kLength = 1024;
-      char buf[kLength];
-      int data_read;
-      do {
-        data_read = read(fd, &buf, kLength);
-      } while (data_read > 0);
-    }
-  }
-
-  void OnUnregistration(int fd, bool replaced) override {
-    recorder_->Record(this, UNREGISTRATION, fd, replaced);
-  }
-
-  void OnShutdown(SimpleEpollServer* eps, int fd) override {
-    if (fd >= 0) {
-      eps->UnregisterFD(fd);
-    }
-    recorder_->Record(this, SHUTDOWN, fd, 0);
-  }
-
-  std::string Name() const override { return "RecordingCB"; }
-
-  const Recorder* recorder() const { return recorder_; }
-
- protected:
-  Recorder* recorder_;
-};
-
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-
-// A simple test server that adds some test functions to SimpleEpollServer as
-// well as allowing access to protected functions.
-class EpollTestServer : public SimpleEpollServer {
- public:
-  EpollTestServer() : SimpleEpollServer() {}
-
-  ~EpollTestServer() override {}
-
-  void CheckMapping(int fd, CB* cb) {
-    CBAndEventMask tmp;
-    tmp.fd = fd;
-    FDToCBMap::iterator fd_i = cb_map_.find(tmp);
-    CHECK(fd_i != cb_map_.end());  // Chokes CHECK_NE.
-    CHECK(fd_i->cb == cb);
-  }
-
-  void CheckNotMapped(int fd) {
-    CBAndEventMask tmp;
-    tmp.fd = fd;
-    FDToCBMap::iterator fd_i = cb_map_.find(tmp);
-    CHECK(fd_i == cb_map_.end());  // Chokes CHECK_EQ.
-  }
-
-  void CheckEventMask(int fd, int event_mask) {
-    CBAndEventMask tmp;
-    tmp.fd = fd;
-    FDToCBMap::iterator fd_i = cb_map_.find(tmp);
-    CHECK(cb_map_.end() != fd_i);  // Chokes CHECK_NE.
-    CHECK_EQ(fd_i->event_mask, event_mask);
-  }
-
-  void CheckNotRegistered(int fd) {
-    struct epoll_event ee;
-    memset(&ee, 0, sizeof(ee));
-    // If the fd is registered, the epoll_ctl call would succeed (return 0) and
-    // the CHECK would fail.
-    CHECK(epoll_ctl(epoll_fd_, EPOLL_CTL_DEL, fd, &ee));
-  }
-
-  size_t GetNumPendingAlarmsForTest() const { return alarm_map_.size(); }
-
-  bool ContainsAlarm(AlarmCB* ac) {
-    return all_alarms_.find(ac) != all_alarms_.end();
-  }
-
-  using SimpleEpollServer::WaitForEventsAndCallHandleEvents;
-};
-
-class EpollFunctionTest : public EpollTest {
- public:
-  EpollFunctionTest()
-      : fd_(-1), fd2_(-1), recorder_(nullptr), cb_(nullptr), ep_(nullptr) {}
-
-  ~EpollFunctionTest() override {
-    delete ep_;
-    delete cb_;
-  }
-
-  void SetUp() override {
-    ep_ = new EpollTestServer();
-    cb_ = new RecordingCB();
-    // recorder_ is safe to use directly as we know it has the same scope as
-    // cb_
-    recorder_ = cb_->recorder();
-
-    int pipe_fds[2];
-    if (pipe(pipe_fds) < 0) {
-      EPOLL_PLOG(FATAL) << "pipe() failed";
-    }
-    fd_ = pipe_fds[0];
-    fd2_ = pipe_fds[1];
-  }
-
-  void TearDown() override {
-    close(fd_);
-    close(fd2_);
-  }
-
-  void DeleteSimpleEpollServer() {
-    delete ep_;
-    ep_ = nullptr;
-  }
-
-  int fd() { return fd_; }
-  int fd2() { return fd2_; }
-  EpollTestServer* ep() { return ep_; }
-  EpollCallbackInterface* cb() { return cb_; }
-  const Recorder* recorder() { return recorder_; }
-
- private:
-  int fd_;
-  int fd2_;
-  const Recorder* recorder_;
-  RecordingCB* cb_;
-  EpollTestServer* ep_;
-};
-
-TEST_F(EpollFunctionTest, TestUnconnectedSocket) {
-  int fd = socket(AddressFamilyUnderTest(), SOCK_STREAM, IPPROTO_TCP);
-  ep()->RegisterFD(fd, cb(), EPOLLIN | EPOLLOUT);
-  ep()->WaitForEventsAndExecuteCallbacks();
-
-  Recorder tmp;
-  tmp.Record(cb(), CREATION, 0, 0);
-  tmp.Record(cb(), REGISTRATION, fd, EPOLLIN | EPOLLOUT);
-  tmp.Record(cb(), EVENT, fd, EPOLLOUT | EPOLLHUP);
-  EXPECT_TRUE(recorder()->IsEqual(&tmp));
-}
-
-TEST_F(EpollFunctionTest, TestRegisterFD) {
-  // Check that the basic register works.
-  ep()->RegisterFD(fd(), cb(), EPOLLIN);
-
-  // Make sure that the fd-CB mapping is there.
-  ep()->CheckMapping(fd(), cb());
-  ep()->CheckEventMask(fd(), EPOLLIN);
-
-  // Now make sure that if we register again, we stomp the old callback.
-  // Also make sure we handle O_NONBLOCK correctly
-  RecordingCB cb2;
-  ep()->RegisterFD(fd(), &cb2, EPOLLOUT | O_NONBLOCK);
-  ep()->CheckMapping(fd(), &cb2);
-  ep()->CheckEventMask(fd(), EPOLLOUT | O_NONBLOCK);
-
-  // Clean up.
-  ep()->UnregisterFD(fd());
-}
-
-TEST_F(EpollFunctionTest, TestRegisterFDForWrite) {
-  ep()->RegisterFDForWrite(fd(), cb());
-  ep()->CheckMapping(fd(), cb());
-  ep()->CheckEventMask(fd(), EPOLLOUT);
-
-  // Clean up.
-  ep()->UnregisterFD(fd());
-}
-
-TEST_F(EpollFunctionTest, TestRegisterFDForReadWrite) {
-  ep()->RegisterFDForReadWrite(fd(), cb());
-  ep()->CheckMapping(fd(), cb());
-  ep()->CheckEventMask(fd(), EPOLLIN | EPOLLOUT);
-
-  // Clean up.
-  ep()->UnregisterFD(fd());
-}
-
-TEST_F(EpollFunctionTest, TestRegisterFDForRead) {
-  ep()->RegisterFDForRead(fd(), cb());
-  ep()->CheckMapping(fd(), cb());
-  ep()->CheckEventMask(fd(), EPOLLIN);
-
-  ep()->UnregisterFD(fd());
-}
-
-TEST_F(EpollFunctionTest, TestUnregisterFD) {
-  ep()->RegisterFDForRead(fd(), cb());
-  ep()->CheckMapping(fd(), cb());
-  ep()->CheckEventMask(fd(), EPOLLIN);
-
-  // Unregister and make sure that it's gone.
-  ep()->UnregisterFD(fd());
-  ep()->CheckNotMapped(fd());
-  ep()->CheckNotRegistered(fd());
-
-  // And make sure that unregistering something a second time doesn't cause
-  // crashes.
-  ep()->UnregisterFD(fd());
-  ep()->CheckNotMapped(fd());
-  ep()->CheckNotRegistered(fd());
-}
-
-TEST_F(EpollFunctionTest, TestModifyCallback) {
-  // Check that nothing terrible happens if we modify an unregistered fd.
-  ep()->ModifyCallback(fd(), EPOLLOUT);
-  ep()->CheckNotMapped(fd());
-  ep()->CheckNotRegistered(fd());
-
-  // Check that the basic register works.
-  ep()->RegisterFD(fd(), cb(), EPOLLIN);
-  ep()->CheckMapping(fd(), cb());
-  ep()->CheckEventMask(fd(), EPOLLIN);
-
-  // Check that adding a signal swaps it out for the first.
-  ep()->ModifyCallback(fd(), EPOLLOUT);
-  ep()->CheckMapping(fd(), cb());
-  ep()->CheckEventMask(fd(), EPOLLOUT);
-
-  // Check that modifying from X to X works correctly.
-  ep()->ModifyCallback(fd(), EPOLLOUT);
-  ep()->CheckMapping(fd(), cb());
-  ep()->CheckEventMask(fd(), EPOLLOUT);
-
-  // Check that modifying from something to nothing works.
-  ep()->ModifyCallback(fd(), 0);
-  ep()->CheckMapping(fd(), cb());
-  ep()->CheckEventMask(fd(), 0);
-
-  ep()->UnregisterFD(fd());
-}
-
-TEST_F(EpollFunctionTest, TestStopRead) {
-  ep()->RegisterFDForReadWrite(fd(), cb());
-  ep()->CheckMapping(fd(), cb());
-  ep()->CheckEventMask(fd(), EPOLLIN | EPOLLOUT);
-
-  // Unregister and make sure you only lose the read event.
-  ep()->StopRead(fd());
-  ep()->CheckMapping(fd(), cb());
-  ep()->CheckEventMask(fd(), EPOLLOUT);
-
-  ep()->UnregisterFD(fd());
-}
-
-TEST_F(EpollFunctionTest, TestStartRead) {
-  ep()->RegisterFDForWrite(fd(), cb());
-  ep()->CheckMapping(fd(), cb());
-  ep()->CheckEventMask(fd(), EPOLLOUT);
-
-  // Make sure that StartRead adds EPOLLIN and doesn't remove other signals.
-  ep()->StartRead(fd());
-  ep()->CheckMapping(fd(), cb());
-  ep()->CheckEventMask(fd(), EPOLLIN | EPOLLOUT);
-
-  // Clean up.
-  ep()->UnregisterFD(fd());
-}
-
-TEST_F(EpollFunctionTest, TestStopWrite) {
-  ep()->RegisterFDForReadWrite(fd(), cb());
-  ep()->CheckMapping(fd(), cb());
-  ep()->CheckEventMask(fd(), EPOLLIN | EPOLLOUT);
-
-  // Unregister write and make sure you only lose the write event.
-  ep()->StopWrite(fd());
-  ep()->CheckMapping(fd(), cb());
-  ep()->CheckEventMask(fd(), EPOLLIN);
-
-  ep()->UnregisterFD(fd());
-}
-
-TEST_F(EpollFunctionTest, TestStartWrite) {
-  ep()->RegisterFDForRead(fd(), cb());
-  ep()->CheckMapping(fd(), cb());
-  ep()->CheckEventMask(fd(), EPOLLIN);
-
-  // Make sure that StartWrite adds EPOLLOUT and doesn't remove other
-  // signals.
-  ep()->StartWrite(fd());
-  ep()->CheckMapping(fd(), cb());
-  ep()->CheckEventMask(fd(), EPOLLIN | EPOLLOUT);
-
-  // Clean up.
-  ep()->UnregisterFD(fd());
-}
-
-TEST_F(EpollFunctionTest, TestSet_timeout_in_us) {
-  // Check that set works with various values.  There's a separate test below
-  // to make sure the values are used properly.
-  ep()->set_timeout_in_us(10);
-  EXPECT_EQ(10, ep()->timeout_in_us_for_test());
-
-  ep()->set_timeout_in_us(-1);
-  EXPECT_EQ(-1, ep()->timeout_in_us_for_test());
-}
-
-TEST_F(EpollFunctionTest, TestHandleEvent) {
-  const std::vector<RecordEntry>* records = recorder()->records();
-
-  // Test that nothing bad happens if the FD is not in the map.
-  ep()->HandleEvent(fd(), EPOLLOUT);
-  ep()->CallReadyListCallbacks();
-
-  ep()->RegisterFD(fd(), cb(), 0);
-  ep()->CheckMapping(fd(), cb());
-  ep()->CheckEventMask(fd(), 0);
-
-  // At this point we should have creation and registration recorded.
-  EXPECT_EQ(2u, records->size());
-
-  // Call handle event and make sure something was recorded.
-  ep()->HandleEvent(fd(), EPOLLOUT);
-  ep()->CallReadyListCallbacks();
-  EXPECT_EQ(3u, records->size());
-
-  // Call handle event and make sure something was recorded.
-  ep()->HandleEvent(fd(), EPOLLIN | O_NONBLOCK);
-  ep()->CallReadyListCallbacks();
-  EXPECT_EQ(4u, records->size());
-
-  Recorder tmp;
-  tmp.Record(cb(), CREATION, 0, 0);
-  tmp.Record(cb(), REGISTRATION, fd(), 0);
-  tmp.Record(cb(), EVENT, fd(), EPOLLOUT);
-  tmp.Record(cb(), EVENT, fd(), EPOLLIN | O_NONBLOCK);
-
-  EXPECT_TRUE(recorder()->IsEqual(&tmp));
-  ep()->UnregisterFD(fd());
-}
-
-TEST_F(EpollFunctionTest, TestNumFDsRegistered) {
-  EXPECT_EQ(0, ep()->NumFDsRegistered());
-
-  ep()->RegisterFD(fd(), cb(), 0);
-  EXPECT_EQ(1, ep()->NumFDsRegistered());
-
-  ep()->RegisterFD(fd2(), cb(), 0);
-  EXPECT_EQ(2, ep()->NumFDsRegistered());
-
-  ep()->RegisterFD(fd2(), cb(), 0);
-  EXPECT_EQ(2, ep()->NumFDsRegistered());
-
-  ep()->UnregisterFD(fd2());
-  EXPECT_EQ(1, ep()->NumFDsRegistered());
-
-  ep()->UnregisterFD(fd());
-  EXPECT_EQ(0, ep()->NumFDsRegistered());
-}
-
-// Check all of the individual signals and 1-2 combinations.
-TEST_F(EpollFunctionTest, TestEventMaskToString) {
-  std::string test;
-
-  test = SimpleEpollServer::EventMaskToString(EPOLLIN);
-  EXPECT_EQ(test, "EPOLLIN ");
-
-  test = SimpleEpollServer::EventMaskToString(EPOLLOUT);
-  EXPECT_EQ(test, "EPOLLOUT ");
-
-  test = SimpleEpollServer::EventMaskToString(EPOLLPRI);
-  EXPECT_EQ(test, "EPOLLPRI ");
-
-  test = SimpleEpollServer::EventMaskToString(EPOLLERR);
-  EXPECT_EQ(test, "EPOLLERR ");
-
-  test = SimpleEpollServer::EventMaskToString(EPOLLHUP);
-  EXPECT_EQ(test, "EPOLLHUP ");
-
-  test = SimpleEpollServer::EventMaskToString(EPOLLHUP | EPOLLIN);
-  EXPECT_EQ(test, "EPOLLIN EPOLLHUP ");
-
-  test = SimpleEpollServer::EventMaskToString(EPOLLIN | EPOLLOUT);
-  EXPECT_EQ(test, "EPOLLIN EPOLLOUT ");
-}
-
-class TestAlarm : public EpollAlarmCallbackInterface {
- public:
-  TestAlarm()
-      : time_before_next_alarm_(-1),
-        was_called_(false),
-        num_called_(0),
-        absolute_time_(false),
-        onshutdown_called_(false),
-        has_token_(false),
-        eps_(nullptr) {}
-  ~TestAlarm() override {}
-  int64_t OnAlarm() override {
-    has_token_ = false;
-    was_called_ = true;
-    ++num_called_;
-    if (time_before_next_alarm_ < 0) {
-      return 0;
-    }
-    if (absolute_time_) {
-      return time_before_next_alarm_;
-    } else {
-      return WallTimeNowInUsec() + time_before_next_alarm_;
-    }
-  }
-
-  void OnShutdown(SimpleEpollServer* /*eps*/) override {
-    onshutdown_called_ = true;
-    has_token_ = false;
-  }
-  void OnRegistration(const SimpleEpollServer::AlarmRegToken& token,
-                      SimpleEpollServer* eps) override {
-    has_token_ = true;
-    last_token_ = token;
-    eps_ = eps;
-  }
-  void OnUnregistration() override { has_token_ = false; }
-
-  void UnregisterIfRegistered(SimpleEpollServer* eps) {
-    if (has_token_) {
-      eps->UnregisterAlarm(last_token_);
-    }
-  }
-
-  void ReregisterAlarm(int64_t timeout_in_us) {
-    CHECK(has_token_);
-    eps_->ReregisterAlarm(last_token_, timeout_in_us);
-  }
-
-  void Reset() {
-    time_before_next_alarm_ = -1;
-    was_called_ = false;
-    absolute_time_ = false;
-  }
-
-  bool was_called() const { return was_called_; }
-  int num_called() const { return num_called_; }
-
-  void set_time_before_next_alarm(int64_t time) {
-    time_before_next_alarm_ = time;
-  }
-  void set_absolute_time(bool absolute) { absolute_time_ = absolute; }
-  bool onshutdown_called() { return onshutdown_called_; }
-
- protected:
-  int64_t time_before_next_alarm_;
-  bool was_called_;
-  int num_called_;
-  // Is time_before_next_alarm relative to the current time or absolute?
-  bool absolute_time_;
-  bool onshutdown_called_;
-  bool has_token_;
-  SimpleEpollServer::AlarmRegToken last_token_;
-  SimpleEpollServer* eps_;
-};
-
-class TestChildAlarm;
-
-// This node unregister all other alarms when it receives
-// OnShutdown() from any one child.
-class TestParentAlarm {
- public:
-  void OnShutdown(TestChildAlarm* child, SimpleEpollServer* eps) {
-    // Unregister
-    for (ChildTokenMap::const_iterator it = child_tokens_.begin();
-         it != child_tokens_.end(); ++it) {
-      if (it->first != child) {
-        eps->UnregisterAlarm(it->second);
-      }
-    }
-    child_tokens_.clear();
-  }
-
-  void OnRegistration(TestChildAlarm* child,
-                      const SimpleEpollServer::AlarmRegToken& token) {
-    child_tokens_[child] = token;
-  }
-
- protected:
-  typedef std::unordered_map<TestChildAlarm*, SimpleEpollServer::AlarmRegToken>
-      ChildTokenMap;
-
-  ChildTokenMap child_tokens_;
-};
-
-class TestChildAlarm : public TestAlarm {
- public:
-  void set_parent(TestParentAlarm* tp) { parent_ = tp; }
-  void OnShutdown(SimpleEpollServer* eps) override {
-    onshutdown_called_ = true;
-    // Inform parent of shutdown
-    parent_->OnShutdown(this, eps);
-  }
-  void OnRegistration(const SimpleEpollServer::AlarmRegToken& token,
-                      SimpleEpollServer* /*eps*/) override {
-    parent_->OnRegistration(this, token);
-  }
-
- protected:
-  TestParentAlarm* parent_;
-};
-
-class TestAlarmThatRegistersAnotherAlarm : public TestAlarm {
- public:
-  TestAlarmThatRegistersAnotherAlarm()
-      : alarm_(nullptr),
-        reg_time_delta_usec_(0),
-        eps_to_register_(nullptr),
-        has_reg_alarm_(false) {}
-  void SetRegisterAlarm(TestAlarm* alarm, int64_t time_delta_usec,
-                        SimpleEpollServer* eps) {
-    alarm_ = alarm;
-    reg_time_delta_usec_ = time_delta_usec;
-    has_reg_alarm_ = true;
-    eps_to_register_ = eps;
-  }
-  int64_t OnAlarm() override {
-    if (has_reg_alarm_) {
-      eps_to_register_->RegisterAlarm(
-          eps_to_register_->ApproximateNowInUsec() + reg_time_delta_usec_,
-          alarm_);
-      has_reg_alarm_ = false;
-    }
-    return TestAlarm::OnAlarm();
-  }
-
- protected:
-  TestAlarm* alarm_;
-  int64_t reg_time_delta_usec_;
-  SimpleEpollServer* eps_to_register_;
-  bool has_reg_alarm_;
-};
-
-class TestAlarmThatRegistersAndReregistersAnotherAlarm : public TestAlarm {
- public:
-  TestAlarmThatRegistersAndReregistersAnotherAlarm()
-      : alarm_(nullptr),
-        reg_time_delta_usec_(0),
-        reregister_time_delta_usec_(0),
-        eps_to_register_(nullptr),
-        has_reg_alarm_(false) {}
-  void SetRegisterAndReregisterAlarm(TestAlarm* alarm, int64_t time_delta_usec,
-                                     int64_t reregister_delta_usec,
-                                     SimpleEpollServer* eps) {
-    alarm_ = alarm;
-    reg_time_delta_usec_ = time_delta_usec;
-    reregister_time_delta_usec_ = reregister_delta_usec;
-    has_reg_alarm_ = true;
-    eps_to_register_ = eps;
-  }
-  int64_t OnAlarm() override {
-    if (has_reg_alarm_) {
-      eps_to_register_->RegisterAlarm(
-          eps_to_register_->ApproximateNowInUsec() + reg_time_delta_usec_,
-          alarm_);
-      alarm_->ReregisterAlarm(eps_to_register_->ApproximateNowInUsec() +
-                              reregister_time_delta_usec_);
-      has_reg_alarm_ = false;
-    }
-    return TestAlarm::OnAlarm();
-  }
-
- protected:
-  TestAlarm* alarm_;
-  int64_t reg_time_delta_usec_;
-  int64_t reregister_time_delta_usec_;
-  SimpleEpollServer* eps_to_register_;
-  bool has_reg_alarm_;
-};
-
-class TestAlarmThatUnregistersAnotherAlarm : public TestAlarm {
- public:
-  TestAlarmThatUnregistersAnotherAlarm()
-      : alarm_(nullptr), eps_to_register_(nullptr), has_unreg_alarm_(false) {}
-  void SetUnregisterAlarm(TestAlarm* alarm, SimpleEpollServer* eps) {
-    alarm_ = alarm;
-    has_unreg_alarm_ = true;
-    eps_to_register_ = eps;
-  }
-  int64_t OnAlarm() override {
-    if (has_unreg_alarm_) {
-      has_unreg_alarm_ = false;
-      alarm_->UnregisterIfRegistered(eps_to_register_);
-    }
-    return TestAlarm::OnAlarm();
-  }
-
- protected:
-  TestAlarm* alarm_;
-  SimpleEpollServer* eps_to_register_;
-  bool has_unreg_alarm_;
-};
-
-class TestAlarmUnregister : public TestAlarm {
- public:
-  TestAlarmUnregister()
-      : onunregistration_called_(false), iterator_token_(nullptr) {}
-  ~TestAlarmUnregister() override { delete iterator_token_; }
-
-  void OnShutdown(SimpleEpollServer* /*eps*/) override {
-    onshutdown_called_ = true;
-  }
-
-  int64_t OnAlarm() override {
-    delete iterator_token_;
-    iterator_token_ = nullptr;
-
-    return TestAlarm::OnAlarm();
-  }
-
-  void OnRegistration(const SimpleEpollServer::AlarmRegToken& token,
-                      SimpleEpollServer* /*eps*/) override {
-    // Multiple iterator tokens are not maintained by this code,
-    // so we should have reset the iterator_token in OnAlarm or
-    // OnUnregistration.
-    CHECK(iterator_token_ == nullptr);
-    iterator_token_ = new SimpleEpollServer::AlarmRegToken(token);
-  }
-  void OnUnregistration() override {
-    delete iterator_token_;
-    iterator_token_ = nullptr;
-    // Make sure that this alarm was not already unregistered.
-    CHECK(onunregistration_called_ == false);
-    onunregistration_called_ = true;
-  }
-
-  bool onunregistration_called() { return onunregistration_called_; }
-  // Returns true if the token has been filled in with the saved iterator
-  // and false if it has not.
-  bool get_token(SimpleEpollServer::AlarmRegToken* token) {
-    if (iterator_token_ != nullptr) {
-      *token = *iterator_token_;
-      return true;
-    } else {
-      return false;
-    }
-  }
-
- protected:
-  bool onunregistration_called_;
-  SimpleEpollServer::AlarmRegToken* iterator_token_;
-};
-
-void WaitForAlarm(SimpleEpollServer* eps, const TestAlarm& alarm) {
-  for (int i = 0; i < 5; ++i) {
-    // Ideally we would only have to call this once but it could wake up a bit
-    // early and so not call the alarm.  If it wakes up early several times
-    // there is something wrong.
-    eps->WaitForEventsAndExecuteCallbacks();
-    if (alarm.was_called()) {
-      break;
-    }
-  }
-}
-
-// Check a couple of alarm times to make sure they're falling within a
-// reasonable range.
-TEST(SimpleEpollServerTest, TestAlarms) {
-  EpollTestServer ep;
-  TestAlarm alarm;
-
-  int alarm_time = 10;
-
-  // Register an alarm and make sure we wait long enough to hit it.
-  ep.set_timeout_in_us(alarm_time * 1000 * 2);
-  ep.RegisterAlarm(WallTimeNowInUsec() + alarm_time, &alarm);
-  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
-  WaitForAlarm(&ep, alarm);
-  EXPECT_TRUE(alarm.was_called());
-  EXPECT_EQ(0u, ep.GetNumPendingAlarmsForTest());
-  alarm.Reset();
-
-  // Test a different time just to be careful.
-  alarm_time = 20;
-  ep.set_timeout_in_us(alarm_time * 1000 * 2);
-  ep.RegisterAlarm(WallTimeNowInUsec() + alarm_time, &alarm);
-  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
-  WaitForAlarm(&ep, alarm);
-  EXPECT_TRUE(alarm.was_called());
-  alarm.Reset();
-
-  // The alarm was a one-time thing.  Make sure that we don't hit it again.
-  EXPECT_EQ(0u, ep.GetNumPendingAlarmsForTest());
-  ep.WaitForEventsAndExecuteCallbacks();
-  EXPECT_FALSE(alarm.was_called());
-  alarm.Reset();
-}
-
-// Same as above, but using RegisterAlarmApproximateDelta.
-TEST(SimpleEpollServerTest, TestRegisterAlarmApproximateDelta) {
-  EpollTestServer ep;
-  TestAlarm alarm;
-
-  int alarm_time = 10;
-
-  // Register an alarm and make sure we wait long enough to hit it.
-  ep.set_timeout_in_us(alarm_time * 1000 * 2);
-  ep.RegisterAlarmApproximateDelta(alarm_time * 1000, &alarm);
-  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
-  WaitForAlarm(&ep, alarm);
-  EXPECT_TRUE(alarm.was_called());
-  EXPECT_EQ(0u, ep.GetNumPendingAlarmsForTest());
-  alarm.Reset();
-  int64_t first_now = ep.ApproximateNowInUsec();
-  EXPECT_LT(0u, first_now);
-
-  // Test a different time just to be careful.
-  alarm_time = 20;
-  ep.set_timeout_in_us(alarm_time * 1000 * 2);
-  ep.RegisterAlarmApproximateDelta(alarm_time * 1000, &alarm);
-  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
-  WaitForAlarm(&ep, alarm);
-  EXPECT_TRUE(alarm.was_called());
-  alarm.Reset();
-  int64_t second_now = ep.ApproximateNowInUsec();
-
-  EXPECT_LT(first_now, second_now);
-
-  // The alarm was a one-time thing.  Make sure that we don't hit it again.
-  EXPECT_EQ(0u, ep.GetNumPendingAlarmsForTest());
-  ep.WaitForEventsAndExecuteCallbacks();
-  EXPECT_FALSE(alarm.was_called());
-  alarm.Reset();
-}
-
-TEST(SimpleEpollServerTest, TestAlarmsWithInfiniteWait) {
-  EpollTestServer ep;
-  TestAlarm alarm;
-
-  int alarm_time = 10;
-
-  // Register an alarm and make sure we wait long enough to hit it.
-  ep.set_timeout_in_us(-1);
-  ep.RegisterAlarm(WallTimeNowInUsec() + alarm_time, &alarm);
-  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
-  WaitForAlarm(&ep, alarm);
-  EXPECT_TRUE(alarm.was_called());
-  EXPECT_EQ(0u, ep.GetNumPendingAlarmsForTest());
-  alarm.Reset();
-}
-
-// In this test we have an alarm that when fires gets re-registered
-// at almost the same time at which it fires. Here, we want to make
-// sure that when the alarm gets re-registered we do not call OnAlarm()
-// on the same Alarm object again, until we have called
-// WaitForEventsAndExecuteCallbacks(). A poor implementation of epoll
-// server alarm handling can potentially cause OnAlarm() to be called
-// multiple times. We make sure that the epoll server is not going in
-// an infinite loop by checking that OnAlarm() is called exactly once
-// on the alarm object that got registered again.
-TEST(SimpleEpollServerTest, TestAlarmsThatGetReRegisteredAreNotCalledTwice) {
-  // This alarm would get registered again
-  TestAlarm alarm;
-  TestAlarm alarm2;
-  EpollTestServer ep;
-  ep.set_timeout_in_us(-1);
-
-  int64_t alarm_time = 10;
-  int64_t abs_time = WallTimeNowInUsec() + alarm_time * 1000;
-
-  // This will make the alarm re-register when OnAlarm is called.
-  alarm.set_absolute_time(true);
-  alarm.set_time_before_next_alarm(abs_time + 2);
-
-  // Register two alarms and make sure we wait long enough to hit it.
-  ep.RegisterAlarm(abs_time, &alarm);
-  ep.RegisterAlarm(abs_time, &alarm2);
-  EXPECT_EQ(2u, ep.GetNumPendingAlarmsForTest());
-
-  WaitForAlarm(&ep, alarm);
-
-  EXPECT_TRUE(alarm.was_called());
-  // Make sure that alarm is called only once.
-  EXPECT_EQ(1, alarm.num_called());
-  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
-  alarm.Reset();
-}
-
-// Here we make sure that when one alarm unregisters another alarm
-// (that is supposed to be registered again because its OnAlarm
-// returned > 0), the alarm thats supposed to be unregistered does
-// actually gets unregistered.
-TEST(SimpleEpollServerTest, TestAlarmsOneOnAlarmUnRegistersAnotherAlarm) {
-  TestAlarm alarm;
-  TestAlarmThatUnregistersAnotherAlarm alarm2;
-  EpollTestServer ep;
-  ep.set_timeout_in_us(-1);
-
-  int64_t alarm_time = 1;
-  int64_t abs_time = WallTimeNowInUsec() + alarm_time * 1000;
-
-  // This will make the alarm re-register when OnAlarm is called.
-  alarm.set_absolute_time(true);
-  alarm.set_time_before_next_alarm(abs_time + 2);
-
-  // Register two alarms and make sure we wait long enough to hit it.
-  ep.RegisterAlarm(abs_time, &alarm);
-  // This would cause us to unregister alarm when OnAlarm is called
-  // on alarm2.
-  alarm2.SetUnregisterAlarm(&alarm, &ep);
-  ep.RegisterAlarm(abs_time + 1, &alarm2);
-  EXPECT_EQ(2u, ep.GetNumPendingAlarmsForTest());
-
-  WaitForAlarm(&ep, alarm);
-
-  EXPECT_TRUE(alarm.was_called());
-  // Make sure that alarm is called only once.
-  EXPECT_EQ(1, alarm.num_called());
-  EXPECT_EQ(0u, ep.GetNumPendingAlarmsForTest());
-  alarm.Reset();
-}
-
-// Check a couple of alarm times to make sure they're falling within a
-// reasonable range.
-TEST(SimpleEpollServerTest, TestRepeatAlarms) {
-  EpollTestServer ep;
-  TestAlarm alarm;
-
-  int alarm_time = 20;
-
-  // Register an alarm and make sure we wait long enough to hit it.
-  ep.set_timeout_in_us(alarm_time * 1000 * 2);
-  alarm.set_time_before_next_alarm(1000 * alarm_time);
-  ep.RegisterAlarm(WallTimeNowInUsec() + alarm_time, &alarm);
-  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
-
-  WaitForAlarm(&ep, alarm);
-  // When we wake up it should be because the Alarm has been called, and has
-  // registered itself to be called again.
-
-  // Make sure the first alarm was called properly.
-  EXPECT_TRUE(alarm.was_called());
-
-  // Resetting means that the alarm is no longer a recurring alarm.  It will be
-  // called once more and then stop.
-  alarm.Reset();
-
-  // Make sure the alarm is called one final time.
-  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
-  ep.set_timeout_in_us(alarm_time * 1000 * 2);
-  WaitForAlarm(&ep, alarm);
-
-  EXPECT_TRUE(alarm.was_called());
-  alarm.Reset();
-
-  // The alarm was a one-time thing.  Make sure that we don't hit it again.
-  EXPECT_EQ(0u, ep.GetNumPendingAlarmsForTest());
-  ep.WaitForEventsAndExecuteCallbacks();
-  EXPECT_FALSE(alarm.was_called());
-}
-
-// Verify that an alarm that repeats itself in the past works properly.
-TEST(SimpleEpollServerTest, TestRepeatAlarmInPast) {
-  EpollTestServer ep;
-  TestAlarm alarm;
-
-  int64_t alarm_time = 20;
-  int64_t abs_time = WallTimeNowInUsec() + alarm_time * 1000;
-
-  // Make the alarm re-register in the past when OnAlarm is called.
-  alarm.set_absolute_time(true);
-  alarm.set_time_before_next_alarm(abs_time - 1000);
-
-  // Register the alarm and make sure we wait long enough to hit it.
-  ep.set_timeout_in_us(alarm_time * 1000 * 2);
-  ep.RegisterAlarm(abs_time, &alarm);
-  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
-
-  WaitForAlarm(&ep, alarm);
-  // When we wake up it should be because the Alarm has been called, and has
-  // registered itself to be called again.
-
-  // Make sure the first alarm was called properly.
-  EXPECT_TRUE(alarm.was_called());
-
-  // Resetting means that the alarm is no longer a recurring alarm.  It will be
-  // called once more and then stop.
-  alarm.Reset();
-
-  // Make sure the alarm is called one final time.
-  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
-  ep.set_timeout_in_us(alarm_time * 1000 * 2);
-  WaitForAlarm(&ep, alarm);
-
-  EXPECT_TRUE(alarm.was_called());
-  alarm.Reset();
-
-  // The alarm was a one-time thing.  Make sure that we don't hit it again.
-  EXPECT_EQ(0u, ep.GetNumPendingAlarmsForTest());
-  ep.WaitForEventsAndExecuteCallbacks();
-  EXPECT_FALSE(alarm.was_called());
-}
-
-class EpollTestAlarms : public SimpleEpollServer {
- public:
-  EpollTestAlarms() : SimpleEpollServer() {}
-
-  inline int64_t NowInUsec() const override { return time_; }
-
-  void CallAndReregisterAlarmEvents() override {
-    recorded_now_in_us_ = NowInUsec();
-    SimpleEpollServer::CallAndReregisterAlarmEvents();
-  }
-
-  void set_time(int64_t time) { time_ = time; }
-
-  size_t GetNumPendingAlarmsForTest() const { return alarm_map_.size(); }
-
- private:
-  int64_t time_;
-};
-
-// Test multiple interleaving alarms to make sure they work right.
-// Pattern is roughly:
-// time:   15    20    30    40
-// alarm:   A     B     A'    C
-TEST(SimpleEpollServerTest, TestMultipleAlarms) {
-  EpollTestAlarms ep;
-  TestAlarm alarmA;
-  TestAlarm alarmB;
-  TestAlarm alarmC;
-
-  ep.set_timeout_in_us(50 * 1000 * 2);
-  alarmA.set_time_before_next_alarm(1000 * 30);
-  alarmA.set_absolute_time(true);
-  ep.RegisterAlarm(15 * 1000, &alarmA);
-  ep.RegisterAlarm(20 * 1000, &alarmB);
-  ep.RegisterAlarm(40 * 1000, &alarmC);
-
-  ep.set_time(15 * 1000);
-  ep.CallAndReregisterAlarmEvents();  // A
-  EXPECT_TRUE(alarmA.was_called());
-  EXPECT_FALSE(alarmB.was_called());
-  EXPECT_FALSE(alarmC.was_called());
-  alarmA.Reset();  // Unregister A in the future.
-
-  ep.set_time(20 * 1000);
-  ep.CallAndReregisterAlarmEvents();  // B
-  EXPECT_FALSE(alarmA.was_called());
-  EXPECT_TRUE(alarmB.was_called());
-  EXPECT_FALSE(alarmC.was_called());
-  alarmB.Reset();
-
-  ep.set_time(30 * 1000);
-  ep.CallAndReregisterAlarmEvents();  // A
-  EXPECT_TRUE(alarmA.was_called());
-  EXPECT_FALSE(alarmB.was_called());
-  EXPECT_FALSE(alarmC.was_called());
-  alarmA.Reset();
-
-  ep.set_time(40 * 1000);
-  ep.CallAndReregisterAlarmEvents();  // C
-  EXPECT_FALSE(alarmA.was_called());
-  EXPECT_FALSE(alarmB.was_called());
-  EXPECT_TRUE(alarmC.was_called());
-  alarmC.Reset();
-
-  ep.CallAndReregisterAlarmEvents();  // None.
-  EXPECT_FALSE(alarmA.was_called());
-  EXPECT_FALSE(alarmB.was_called());
-  EXPECT_FALSE(alarmC.was_called());
-}
-
-TEST(SimpleEpollServerTest, TestAlarmOnShutdown) {
-  TestAlarm alarm1;
-  {
-    EpollTestServer ep;
-    const int64_t now = WallTimeNowInUsec();
-    ep.RegisterAlarm(now + 5000, &alarm1);
-  }
-
-  EXPECT_TRUE(alarm1.onshutdown_called());
-}
-
-// Tests that if we have multiple alarms
-// OnShutdown then we handle them properly.
-TEST(SimpleEpollServerTest, TestMultipleAlarmOnShutdown) {
-  TestAlarm alarm1;
-  TestAlarm alarm2;
-  TestAlarm alarm3;
-  {
-    EpollTestServer ep;
-    const int64_t now = WallTimeNowInUsec();
-    ep.RegisterAlarm(now + 5000, &alarm1);
-    ep.RegisterAlarm(now + 9000, &alarm2);
-    ep.RegisterAlarm(now + 9000, &alarm3);
-  }
-
-  EXPECT_TRUE(alarm1.onshutdown_called());
-  EXPECT_TRUE(alarm2.onshutdown_called());
-  EXPECT_TRUE(alarm3.onshutdown_called());
-}
-TEST(SimpleEpollServerTest, TestMultipleAlarmUnregistrationOnShutdown) {
-  TestParentAlarm tp;
-  TestChildAlarm alarm1;
-  TestChildAlarm alarm2;
-  alarm1.set_parent(&tp);
-  alarm2.set_parent(&tp);
-  {
-    EpollTestServer ep;
-    const int64_t now = WallTimeNowInUsec();
-    ep.RegisterAlarm(now + 5000, &alarm1);
-    ep.RegisterAlarm(now + 9000, &alarm2);
-  }
-
-  EXPECT_TRUE(alarm1.onshutdown_called());
-  EXPECT_FALSE(alarm2.onshutdown_called());
-}
-
-// Check an alarm set in the past runs right away.
-TEST(SimpleEpollServerTest, TestPastAlarm) {
-  EpollTestServer ep;
-  TestAlarm alarm;
-
-  // Register the alarm and make sure we wait long enough to hit it.
-  ep.set_timeout_in_us(1000 * 2);
-  ep.RegisterAlarm(WallTimeNowInUsec() - 1000, &alarm);
-  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
-  ep.WaitForEventsAndExecuteCallbacks();
-  EXPECT_TRUE(alarm.was_called());
-  EXPECT_EQ(0u, ep.GetNumPendingAlarmsForTest());
-  alarm.Reset();
-}
-
-// Test Unregistering of Alarms
-TEST(SimpleEpollServerTest, TestUnregisterAlarm) {
-  EpollTestServer ep;
-  SimpleEpollServer::AlarmRegToken temptok;
-
-  TestAlarmUnregister alarm1;
-  TestAlarmUnregister alarm2;
-
-  ep.RegisterAlarm(WallTimeNowInUsec() + 5 * 1000, &alarm1);
-  ep.RegisterAlarm(WallTimeNowInUsec() + 13 * 1000, &alarm2);
-
-  // Unregister an alarm.
-  if (alarm2.get_token(&temptok)) {
-    ep.UnregisterAlarm(temptok);
-  }
-  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
-  EXPECT_TRUE(alarm2.onunregistration_called());
-
-  if (alarm1.get_token(&temptok)) {
-    ep.UnregisterAlarm(temptok);
-  }
-  EXPECT_EQ(0u, ep.GetNumPendingAlarmsForTest());
-  EXPECT_TRUE(alarm1.onunregistration_called());
-}
-
-// Test Reregistering of Alarms
-TEST(SimpleEpollServerTest, TestReregisterAlarm) {
-  EpollTestAlarms ep;
-  SimpleEpollServer::AlarmRegToken token;
-
-  TestAlarmUnregister alarm;
-  ep.set_time(1000);
-  ep.RegisterAlarm(5000, &alarm);
-
-  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
-  ASSERT_TRUE(alarm.get_token(&token));
-  ep.ReregisterAlarm(token, 6000);
-  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
-
-  ep.set_time(5000);
-  ep.set_timeout_in_us(0);
-  ep.CallAndReregisterAlarmEvents();
-  EXPECT_FALSE(alarm.was_called());
-
-  ep.set_time(6000);
-  ep.CallAndReregisterAlarmEvents();
-  EXPECT_TRUE(alarm.was_called());
-}
-
-TEST(SimpleEpollServerTest, TestReregisterDeferredAlarm) {
-  EpollTestAlarms ep;
-  ep.set_timeout_in_us(0);
-
-  TestAlarm alarm;
-  TestAlarmThatRegistersAndReregistersAnotherAlarm register_alarm;
-  // Register the alarm in the past so it is added as a deferred alarm.
-  register_alarm.SetRegisterAndReregisterAlarm(&alarm, -500, 500, &ep);
-  ep.set_time(1000);
-  ep.RegisterAlarm(1000, &register_alarm);
-  // Call reregister twice, first to run register_alarm and second to run any
-  // scheduled deferred alarms.
-  ep.CallAndReregisterAlarmEvents();
-  ep.CallAndReregisterAlarmEvents();
-
-  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
-  EXPECT_FALSE(alarm.was_called());
-
-  ep.set_time(1500);
-  ep.CallAndReregisterAlarmEvents();
-  EXPECT_TRUE(alarm.was_called());
-}
-
-// Check if an alarm fired and got reregistered, you are able to
-// unregister the second registration.
-TEST(SimpleEpollServerTest, TestFiredReregisteredAlarm) {
-  EpollTestAlarms ep;
-  TestAlarmUnregister alarmA;
-
-  SimpleEpollServer::AlarmRegToken first_token;
-  SimpleEpollServer::AlarmRegToken second_token;
-  bool found;
-
-  ep.set_timeout_in_us(50 * 1000 * 2);
-  alarmA.set_time_before_next_alarm(1000 * 30);
-  alarmA.set_absolute_time(true);
-
-  // Alarm A first fires at 15, then 30
-  ep.RegisterAlarm(15 * 1000, &alarmA);
-
-  found = alarmA.get_token(&first_token);
-  EXPECT_TRUE(found);
-
-  ep.set_time(15 * 1000);
-  ep.CallAndReregisterAlarmEvents();  // A
-  EXPECT_TRUE(alarmA.was_called());
-
-  alarmA.Reset();
-
-  found = alarmA.get_token(&second_token);
-  EXPECT_TRUE(found);
-  if (found) {
-    ep.UnregisterAlarm(second_token);
-  }
-
-  ep.set_time(30 * 1000);
-  ep.CallAndReregisterAlarmEvents();  // A
-
-  alarmA.Reset();
-}
-
-// Here we make sure that one alarm can unregister another alarm
-// in OnShutdown().
-TEST(SimpleEpollServerTest, TestAlarmCanUnregistersAnotherAlarmOnShutdown) {
-  TestAlarmThatUnregistersAnotherAlarm alarm1;
-  TestAlarm alarm2;
-  {
-    EpollTestServer ep;
-    // Register two alarms and make alarm1 is placed in queue in front of alarm2
-    // so that when the queue is cleared, alarm1 is processed first.
-    const int64_t now = WallTimeNowInUsec();
-    ep.RegisterAlarm(now + 5000, &alarm1);
-    ep.RegisterAlarm(now + 9000, &alarm2);
-    alarm1.SetUnregisterAlarm(&alarm2, &ep);
-    EXPECT_EQ(2u, ep.GetNumPendingAlarmsForTest());
-  }
-}
-
-class TestAlarmRegisterAnotherAlarmShutdown : public TestAlarmUnregister {
- public:
-  TestAlarmRegisterAnotherAlarmShutdown(EpollAlarmCallbackInterface* alarm2,
-                                        int64_t when)
-      : alarm2_(alarm2), when_(when) {}
-  void OnShutdown(SimpleEpollServer* eps) override {
-    TestAlarmUnregister::OnShutdown(eps);
-    eps->RegisterAlarm(when_, alarm2_);
-  }
-
- private:
-  EpollAlarmCallbackInterface* alarm2_;
-  int64_t when_;
-};
-
-// This tests that alarm registers another alarm when shutting down.
-// The two cases are: new alarm comes before and after the alarm being
-// notified by OnShutdown()
-TEST(SimpleEpollServerTest, AlarmRegistersAnotherAlarmOnShutdownBeforeSelf) {
-  TestAlarm alarm2;
-  int64_t alarm_time = WallTimeNowInUsec() + 5000;
-  TestAlarmRegisterAnotherAlarmShutdown alarm1(&alarm2, alarm_time - 1000);
-  {
-    EpollTestAlarms ep;
-    ep.RegisterAlarm(alarm_time, &alarm1);
-  }
-  EXPECT_TRUE(alarm1.onshutdown_called());
-  EXPECT_FALSE(alarm2.onshutdown_called());
-}
-
-TEST(SimpleEpollServerTest, AlarmRegistersAnotherAlarmOnShutdownAfterSelf) {
-  TestAlarm alarm2;
-  int64_t alarm_time = WallTimeNowInUsec() + 5000;
-  TestAlarmRegisterAnotherAlarmShutdown alarm1(&alarm2, alarm_time + 1000);
-  {
-    EpollTestAlarms ep;
-    ep.RegisterAlarm(alarm_time, &alarm1);
-  }
-  EXPECT_TRUE(alarm1.onshutdown_called());
-  EXPECT_TRUE(alarm2.onshutdown_called());
-}
-
-TEST(SimpleEpollServerTest, TestWrite) {
-  SimpleEpollServer ep;
-  ep.set_timeout_in_us(1);
-  char data[kPageSize] = {0};
-
-  int pipe_fds[2];
-  if (pipe(pipe_fds) < 0) {
-    EPOLL_PLOG(FATAL) << "pipe() failed";
-  }
-  int read_fd = pipe_fds[0];
-  int write_fd = pipe_fds[1];
-
-  RecordingCB recording_cb;
-  const Recorder* recorder = recording_cb.recorder();
-  const std::vector<RecordEntry>* records = recorder->records();
-
-  // Register to listen to write events.
-  ep.RegisterFD(write_fd, &recording_cb, EPOLLOUT | O_NONBLOCK);
-  // At this point the recorder should have the creation and registration
-  // events.
-  EXPECT_EQ(2u, records->size());
-
-  // Fill up the pipe.
-  int written = 1;
-  for (int i = 0; i < 17 && written > 0; ++i) {
-    written = write(write_fd, &data, kPageSize);
-  }
-  EXPECT_LT(written, 0);
-
-  // There should be no new events as the pipe is not available for writing.
-  ep.WaitForEventsAndExecuteCallbacks();
-  EXPECT_EQ(2u, records->size());
-
-  // Now read data from the pipe to make it writable again.  This time the
-  // we should get an EPOLLOUT event.
-  int size = read(read_fd, &data, kPageSize);
-  EXPECT_EQ(kPageSize, size);
-  ep.WaitForEventsAndExecuteCallbacks();
-  EXPECT_EQ(3u, records->size());
-
-  // Now unsubscribe from writable events (which adds a modification record)
-  // and wait to verify that no event records are added.
-  ep.StopWrite(write_fd);
-  ep.WaitForEventsAndExecuteCallbacks();
-  EXPECT_EQ(4u, records->size());
-
-  // We had the right number of events all along. Make sure they were actually
-  // the right events.
-  Recorder tmp;
-  tmp.Record(&recording_cb, CREATION, 0, 0);
-  tmp.Record(&recording_cb, REGISTRATION, write_fd, EPOLLOUT | O_NONBLOCK);
-  tmp.Record(&recording_cb, EVENT, write_fd, EPOLLOUT);
-  tmp.Record(&recording_cb, MODIFICATION, write_fd, O_NONBLOCK);
-
-  EXPECT_TRUE(recorder->IsEqual(&tmp));
-  ep.UnregisterFD(write_fd);
-
-  close(read_fd);
-  close(write_fd);
-}
-
-TEST(SimpleEpollServerTest, TestReadWrite) {
-  SimpleEpollServer ep;
-  ep.set_timeout_in_us(1);
-  char data[kPageSize] = {0};
-
-  int pipe_fds[2];
-  if (pipe(pipe_fds) < 0) {
-    EPOLL_PLOG(FATAL) << "pipe() failed";
-  }
-  int read_fd = pipe_fds[0];
-  int write_fd = pipe_fds[1];
-
-  RecordingCB recording_cb;
-  const Recorder* recorder = recording_cb.recorder();
-  const std::vector<RecordEntry>* records = recorder->records();
-
-  // Register to listen to read and write events.
-  ep.RegisterFDForReadWrite(read_fd, &recording_cb);
-  // At this point the recorder should have the creation and registration
-  // events.
-  EXPECT_EQ(2u, records->size());
-
-  int written = write(write_fd, &data, kPageSize);
-  EXPECT_EQ(kPageSize, written);
-
-  ep.WaitForEventsAndExecuteCallbacks();
-  ep.UnregisterFD(read_fd);
-
-  close(read_fd);
-  close(write_fd);
-}
-
-TEST(SimpleEpollServerTest, TestMultipleFDs) {
-  SimpleEpollServer ep;
-  ep.set_timeout_in_us(1);
-  char data = 'x';
-
-  int pipe_one[2];
-  if (pipe(pipe_one) < 0) {
-    EPOLL_PLOG(FATAL) << "pipe() failed";
-  }
-  int pipe_two[2];
-  if (pipe(pipe_two) < 0) {
-    EPOLL_PLOG(FATAL) << "pipe() failed";
-  }
-
-  RecordingCB recording_cb_one;
-  const Recorder* recorder_one = recording_cb_one.recorder();
-  const std::vector<RecordEntry>* records_one = recorder_one->records();
-
-  RecordingCB recording_cb_two;
-  const Recorder* recorder_two = recording_cb_two.recorder();
-  const std::vector<RecordEntry>* records_two = recorder_two->records();
-
-  // Register to listen to read events for both pipes
-  ep.RegisterFDForRead(pipe_one[0], &recording_cb_one);
-  ep.RegisterFDForRead(pipe_two[0], &recording_cb_two);
-
-  EXPECT_EQ(2u, records_one->size());
-  EXPECT_EQ(2u, records_two->size());
-
-  EXPECT_EQ(1, write(pipe_one[1], &data, 1));
-  ep.WaitForEventsAndExecuteCallbacks();
-  EXPECT_EQ(3u, records_one->size());
-  EXPECT_EQ(2u, records_two->size());
-
-  EXPECT_EQ(1, write(pipe_two[1], &data, 1));
-  ep.WaitForEventsAndExecuteCallbacks();
-  EXPECT_EQ(3u, records_one->size());
-  EXPECT_EQ(3u, records_two->size());
-
-  EXPECT_EQ(1, write(pipe_one[1], &data, 1));
-  EXPECT_EQ(1, write(pipe_two[1], &data, 1));
-  ep.WaitForEventsAndExecuteCallbacks();
-  EXPECT_EQ(4u, records_one->size());
-  EXPECT_EQ(4u, records_two->size());
-
-  ep.WaitForEventsAndExecuteCallbacks();
-  ep.UnregisterFD(pipe_one[0]);
-  ep.UnregisterFD(pipe_two[0]);
-  close(pipe_one[0]);
-  close(pipe_one[1]);
-  close(pipe_two[0]);
-  close(pipe_two[1]);
-}
-
-// Check that the SimpleEpollServer calls OnShutdown for any registered FDs.
-TEST(SimpleEpollServerTest, TestFDOnShutdown) {
-  int pipe_fds[2];
-  if (pipe(pipe_fds) < 0) {
-    EPOLL_PLOG(FATAL) << "pipe() failed";
-  }
-  int read_fd = pipe_fds[0];
-  int write_fd = pipe_fds[1];
-
-  RecordingCB recording_cb1;
-  RecordingCB recording_cb2;
-  const Recorder* recorder1 = recording_cb1.recorder();
-  const Recorder* recorder2 = recording_cb2.recorder();
-
-  {
-    SimpleEpollServer ep;
-    ep.set_timeout_in_us(1);
-
-    // Register to listen to write events.
-    ep.RegisterFD(write_fd, &recording_cb1, EPOLLOUT | O_NONBLOCK);
-    ep.RegisterFD(read_fd, &recording_cb2, EPOLLIN | O_NONBLOCK);
-  }
-
-  // Make sure OnShutdown was called for both callbacks.
-  Recorder write_recorder;
-  write_recorder.Record(&recording_cb1, CREATION, 0, 0);
-  write_recorder.Record(&recording_cb1, REGISTRATION, write_fd,
-                        EPOLLOUT | O_NONBLOCK);
-  write_recorder.Record(&recording_cb1, UNREGISTRATION, write_fd, false);
-  write_recorder.Record(&recording_cb1, SHUTDOWN, write_fd, 0);
-  EXPECT_TRUE(recorder1->IsEqual(&write_recorder));
-
-  Recorder read_recorder;
-  read_recorder.Record(&recording_cb2, CREATION, 0, 0);
-  read_recorder.Record(&recording_cb2, REGISTRATION, read_fd,
-                       EPOLLIN | O_NONBLOCK);
-  read_recorder.Record(&recording_cb2, UNREGISTRATION, read_fd, false);
-  read_recorder.Record(&recording_cb2, SHUTDOWN, read_fd, 0);
-  EXPECT_TRUE(recorder2->IsEqual(&read_recorder));
-
-  close(read_fd);
-  close(write_fd);
-}
-
-class UnregisterCB : public EpollCallbackInterface {
- public:
-  explicit UnregisterCB(int fd)
-      : eps_(nullptr), fd_(fd), onshutdown_called_(false) {}
-
-  ~UnregisterCB() override {}
-
-  void OnShutdown(SimpleEpollServer* /*eps*/, int fd) override {
-    eps_->UnregisterFD(fd_);
-    eps_->UnregisterFD(fd);
-    onshutdown_called_ = true;
-    eps_ = nullptr;
-  }
-
-  void set_epollserver(SimpleEpollServer* eps) { eps_ = eps; }
-  bool onshutdown_called() { return onshutdown_called_; }
-
-  void OnRegistration(SimpleEpollServer* /*eps*/, int /*fd*/,
-                      int /*event_mask*/) override {}
-  void OnModification(int /*fd*/, int /*event_mask*/) override {}
-  void OnEvent(int /*fd*/, EpollEvent* /*event*/) override {}
-  void OnUnregistration(int /*fd*/, bool /*replaced*/) override {}
-
-  std::string Name() const override { return "UnregisterCB"; }
-
- protected:
-  SimpleEpollServer* eps_;
-  int fd_;
-  bool onshutdown_called_;
-};
-
-// Check that unregistering fds in OnShutdown works cleanly.
-TEST(SimpleEpollServerTest, TestUnregisteringFDsOnShutdown) {
-  int pipe_fds[2];
-  if (pipe(pipe_fds) < 0) {
-    EPOLL_PLOG(FATAL) << "pipe() failed";
-  }
-  int read_fd = pipe_fds[0];
-  int write_fd = pipe_fds[1];
-
-  UnregisterCB unreg_cb1(read_fd);
-  UnregisterCB unreg_cb2(write_fd);
-
-  {
-    SimpleEpollServer ep;
-    ep.set_timeout_in_us(1);
-
-    unreg_cb1.set_epollserver(&ep);
-    unreg_cb2.set_epollserver(&ep);
-
-    // Register to listen to write events.
-    ep.RegisterFD(write_fd, &unreg_cb1, EPOLLOUT | O_NONBLOCK);
-    ep.RegisterFD(read_fd, &unreg_cb2, EPOLLIN | O_NONBLOCK);
-  }
-
-  // Make sure at least one onshutdown was called.
-  EXPECT_TRUE(unreg_cb1.onshutdown_called() || unreg_cb2.onshutdown_called());
-  // Make sure that both onshutdowns were not called.
-  EXPECT_TRUE(
-      !(unreg_cb1.onshutdown_called() && unreg_cb2.onshutdown_called()));
-
-  close(read_fd);
-  close(write_fd);
-}
-
-TEST(SimpleEpollServerTest, TestFDsAndAlarms) {
-  SimpleEpollServer ep;
-  ep.set_timeout_in_us(5);
-  char data = 'x';
-
-  int pipe_fds[2];
-  if (pipe(pipe_fds) < 0) {
-    EPOLL_PLOG(FATAL) << "pipe() failed";
-  }
-
-  RecordingCB recording_cb;
-  const Recorder* recorder = recording_cb.recorder();
-  const std::vector<RecordEntry>* records = recorder->records();
-
-  TestAlarm alarm;
-
-  ep.RegisterFDForRead(pipe_fds[0], &recording_cb);
-
-  EXPECT_EQ(2u, records->size());
-  EXPECT_FALSE(alarm.was_called());
-
-  // Write to the pipe and set a longish alarm so we get a read event followed
-  // by an alarm event.
-  int written = write(pipe_fds[1], &data, 1);
-  EXPECT_EQ(1, written);
-  ep.WaitForEventsAndExecuteCallbacks();
-  EXPECT_EQ(3u, records->size());
-  EXPECT_FALSE(alarm.was_called());
-  ep.RegisterAlarm(WallTimeNowInUsec() + 1000, &alarm);
-  WaitForAlarm(&ep, alarm);
-  EXPECT_EQ(3u, records->size());
-  EXPECT_TRUE(alarm.was_called());
-  alarm.Reset();
-
-  // Now set a short alarm so the alarm and the read event are called together.
-  ep.RegisterAlarm(WallTimeNowInUsec(), &alarm);
-  written = write(pipe_fds[1], &data, 1);
-  EXPECT_EQ(1, written);
-  ep.WaitForEventsAndExecuteCallbacks();
-  EXPECT_TRUE(alarm.was_called());
-  EXPECT_EQ(4u, records->size());
-
-  ep.UnregisterFD(pipe_fds[0]);
-
-  close(pipe_fds[0]);
-  close(pipe_fds[1]);
-}
-
-class EpollReader : public EpollCallbackInterface {
- public:
-  explicit EpollReader(int len)
-      : len_(0), expected_len_(len), done_reading_(false) {
-    memset(&buf_, 0, kMaxBufLen);
-  }
-
-  ~EpollReader() override {}
-
-  void OnRegistration(SimpleEpollServer* /*eps*/, int /*fd*/,
-                      int /*event_mask*/) override {}
-
-  void OnModification(int /*fd*/, int /*event_mask*/) override {}
-
-  void OnEvent(int fd, EpollEvent* event) override {
-    if (event->in_events & EPOLLIN) {
-      len_ += read(fd, &buf_ + len_, kMaxBufLen - len_);
-    }
-
-    // If we have finished reading...
-    if (event->in_events & EPOLLHUP) {
-      CHECK_EQ(len_, expected_len_);
-      done_reading_ = true;
-    }
-  }
-
-  void OnUnregistration(int /*fd*/, bool /*replaced*/) override {}
-
-  void OnShutdown(SimpleEpollServer* /*eps*/, int /*fd*/) override {
-    // None of the current tests involve having active callbacks when the
-    // server shuts down.
-    EPOLL_LOG(FATAL);
-  }
-
-  std::string Name() const override { return "EpollReader"; }
-
-  // Returns true if the data in buf is the same as buf_, false otherwise.
-  bool CheckOutput(char* buf, int len) {
-    if (len != len_) {
-      return false;
-    }
-    return !memcmp(buf, buf_, len);
-  }
-
-  bool done_reading() { return done_reading_; }
-
- protected:
-  int len_;
-  int expected_len_;
-  char buf_[kMaxBufLen];
-  bool done_reading_;
-};
-
-void TestPipe(char* test_message, int len) {
-  int pipe_fds[2];
-  if (pipe(pipe_fds) < 0) {
-    EPOLL_PLOG(FATAL) << "pipe failed()";
-  }
-  int reader_pipe = pipe_fds[0];
-  int writer_pipe = pipe_fds[1];
-  int child_pid;
-  memset(test_message, 'x', len);
-
-  switch (child_pid = fork()) {
-    case 0: {  // Child will send message.
-      const char* message = test_message;
-      int size;
-      close(reader_pipe);
-      while ((size = write(writer_pipe, message, len)) > 0) {
-        message += size;
-        len -= size;
-        if (len == 0) {
-          break;
-        }
-      }
-      if (len > 0) {
-        EPOLL_PLOG(FATAL) << "write() failed";
-      }
-      close(writer_pipe);
-
-      _exit(0);
-    }
-    case -1:
-      EPOLL_PLOG(FATAL) << "fork() failed";
-      break;
-    default: {  // Parent will receive message.
-      close(writer_pipe);
-      auto ep = std::make_unique<SimpleEpollServer>();
-      ep->set_timeout_in_us(1);
-      EpollReader reader(len);
-      ep->RegisterFD(reader_pipe, &reader, EPOLLIN);
-
-      int64_t start_ms = WallTimeNowInUsec() / 1000;
-      // Loop until we're either done reading, or have waited ~10 us.
-      while (!reader.done_reading() &&
-             (WallTimeNowInUsec() / 1000 - start_ms) < 10000) {
-        ep->WaitForEventsAndExecuteCallbacks();
-      }
-      ep->UnregisterFD(reader_pipe);
-      CHECK(reader.CheckOutput(test_message, len));
-      break;
-    }
-  }
-
-  close(reader_pipe);
-  close(writer_pipe);
-}
-
-TEST(SimpleEpollServerTest, TestSmallPipe) {
-  char buf[kMaxBufLen];
-  TestPipe(buf, 10);
-}
-
-TEST(SimpleEpollServerTest, TestLargePipe) {
-  char buf[kMaxBufLen];
-  TestPipe(buf, kMaxBufLen);
-}
-
-// Tests RegisterFDForRead as well as StopRead.
-TEST(SimpleEpollServerTest, TestRead) {
-  SimpleEpollServer ep;
-  ep.set_timeout_in_us(1);
-  int len = 1;
-
-  int pipe_fds[2];
-  if (pipe(pipe_fds) < 0) {
-    EPOLL_PLOG(FATAL) << "pipe() failed";
-  }
-  int read_fd = pipe_fds[0];
-  int write_fd = pipe_fds[1];
-
-  auto reader = std::make_unique<EpollReader>(len);
-
-  // Check that registering a FD for read alerts us when there is data to be
-  // read.
-  ep.RegisterFDForRead(read_fd, reader.get());
-  char data = 'a';
-  int size = write(write_fd, &data, 1);
-  EXPECT_EQ(1, size);
-  ep.WaitForEventsAndExecuteCallbacks();
-  EXPECT_TRUE(reader->CheckOutput(&data, len));
-
-  // Remove the callback for read events, write to the pipe and make sure that
-  // we did not read more data.
-  ep.StopRead(read_fd);
-  size = write(write_fd, &data, len);
-  EXPECT_EQ(1, size);
-  // The wait will return after timeout.
-  ep.WaitForEventsAndExecuteCallbacks();
-  EXPECT_TRUE(reader->CheckOutput(&data, len));
-  ep.UnregisterFD(read_fd);
-
-  close(read_fd);
-  close(write_fd);
-}
-
-class EdgeTriggerCB : public EpollCallbackInterface {
- public:
-  EdgeTriggerCB(int read_size, int write_size, char write_char, char peer_char)
-      : eps_(nullptr),
-        read_buf_(read_size),
-        write_buf_(write_size, write_char),
-        peer_char_(peer_char) {
-    Reset();
-  }
-
-  ~EdgeTriggerCB() override {}
-
-  void Reset() {
-    CHECK(eps_ == nullptr);
-    bytes_read_ = 0;
-    bytes_written_ = 0;
-    can_read_ = false;
-    will_read_ = false;
-    can_write_ = false;
-    will_write_ = false;
-    read_closed_ = false;
-    write_closed_ = false;
-  }
-
-  void ResetByteCounts() { bytes_read_ = bytes_written_ = 0; }
-
-  void set_will_read(bool will_read) { will_read_ = will_read; }
-
-  void set_will_write(bool will_write) { will_write_ = will_write; }
-
-  bool can_write() const { return can_write_; }
-
-  int bytes_read() const { return bytes_read_; }
-
-  int bytes_written() const { return bytes_written_; }
-
-  void OnRegistration(SimpleEpollServer* eps, int fd, int event_mask) override {
-    EXPECT_TRUE(eps_ == nullptr);
-    eps_ = eps;
-    Initialize(fd, event_mask);
-  }
-
-  void OnModification(int fd, int event_mask) override {
-    EXPECT_TRUE(eps_ != nullptr);
-    if (event_mask & EPOLLET) {
-      Initialize(fd, event_mask);
-    } else {
-      eps_->SetFDNotReady(fd);
-    }
-  }
-
-  void OnEvent(int fd, EpollEvent* event) override {
-    const int event_mask = event->in_events;
-    if (event_mask & (EPOLLHUP | EPOLLERR)) {
-      write_closed_ = true;
-      return;
-    }
-    if (will_read_ && event_mask & EPOLLIN) {
-      EXPECT_FALSE(read_closed_);
-      int read_size = read_buf_.size();
-      memset(&read_buf_[0], 0, read_size);
-      int len = recv(fd, &read_buf_[0], read_size, MSG_DONTWAIT);
-      // Update the readiness states
-      can_read_ = (len == read_size);
-
-      if (len > 0) {
-        bytes_read_ += len;
-        EPOLL_VLOG(1) << "fd: " << fd << ", read " << len
-                      << ", total: " << bytes_read_;
-        // Now check the bytes read
-        EXPECT_TRUE(CheckReadBuffer(len));
-      } else if (len < 0) {
-        EPOLL_VLOG(1) << "fd: " << fd << " read hit EAGAIN";
-        EXPECT_EQ(EAGAIN, errno) << strerror(errno);
-        can_read_ = false;
-      } else {
-        read_closed_ = true;
-      }
-    }
-    if (will_write_ && event_mask & EPOLLOUT) {
-      // Write side close/full close can only detected by EPOLLHUP, which is
-      // caused by EPIPE.
-      EXPECT_FALSE(write_closed_);
-      int write_size = write_buf_.size();
-      int len = send(fd, &write_buf_[0], write_size, MSG_DONTWAIT);
-      can_write_ = (len == write_size);
-      if (len > 0) {
-        bytes_written_ += len;
-        EPOLL_VLOG(1) << "fd: " << fd << ", write " << len
-                      << ", total: " << bytes_written_;
-      } else {
-        EPOLL_VLOG(1) << "fd: " << fd << " write hit EAGAIN";
-        EXPECT_EQ(EAGAIN, errno) << strerror(errno);
-        can_write_ = false;
-      }
-    }
-    // Since we can only get on the ready list once, wait till we confirm both
-    // read and write side continuation state and set the correct event mask
-    // for the ready list.
-    event->out_ready_mask = can_read_ ? static_cast<int>(EPOLLIN) : 0;
-    if (can_write_) {
-      event->out_ready_mask |= EPOLLOUT;
-    }
-  }
-
-  void OnUnregistration(int /*fd*/, bool /*replaced*/) override {
-    EXPECT_TRUE(eps_ != nullptr);
-    eps_ = nullptr;
-  }
-
-  void OnShutdown(SimpleEpollServer* /*eps*/, int /*fd*/) override {
-    // None of the current tests involve having active callbacks when the
-    // server shuts down.
-    EPOLL_LOG(FATAL);
-  }
-
-  std::string Name() const override { return "EdgeTriggerCB"; }
-
- private:
-  SimpleEpollServer* eps_;
-  std::vector<char> read_buf_;
-  int bytes_read_;
-  std::vector<char> write_buf_;
-  int bytes_written_;
-  char peer_char_;  // The char we expected to read.
-  bool can_read_;
-  bool will_read_;
-  bool can_write_;
-  bool will_write_;
-  bool read_closed_;
-  bool write_closed_;
-
-  void Initialize(int fd, int event_mask) {
-    CHECK(eps_);
-    can_read_ = can_write_ = false;
-    if (event_mask & EPOLLET) {
-      int events = 0;
-      if (event_mask & EPOLLIN) {
-        events |= EPOLLIN;
-        can_read_ = true;
-      }
-      if (event_mask & EPOLLOUT) {
-        events |= EPOLLOUT;
-        can_write_ = true;
-      }
-      eps_->SetFDReady(fd, events);
-    }
-  }
-
-  bool CheckReadBuffer(int len) const {
-    for (int i = 0; i < len; ++i) {
-      if (peer_char_ != read_buf_[i]) {
-        return false;
-      }
-    }
-    return true;
-  }
-};
-
-// Test adding and removing from the ready list.
-TEST(SimpleEpollServerTest, TestReadyList) {
-  SimpleEpollServer ep;
-  int pipe_fds[2];
-  if (pipe(pipe_fds) < 0) {
-    EPOLL_PLOG(FATAL) << "pipe() failed";
-  }
-
-  // Just use any CB will do, since we never wait on epoll events.
-  EdgeTriggerCB reader1(0, 0, 0, 0);
-  EdgeTriggerCB reader2(0, 0, 0, 0);
-
-  ep.RegisterFD(pipe_fds[0], &reader1, EPOLLIN);
-  ep.RegisterFD(pipe_fds[1], &reader2, EPOLLOUT);
-
-  // Adding fds that are registered with eps
-  EXPECT_FALSE(ep.IsFDReady(pipe_fds[0]));
-  EXPECT_FALSE(ep.IsFDReady(pipe_fds[1]));
-
-  ep.SetFDReady(pipe_fds[0], EPOLLIN);
-  EXPECT_TRUE(ep.IsFDReady(pipe_fds[0]));
-  EXPECT_FALSE(ep.IsFDReady(pipe_fds[1]));
-  EXPECT_EQ(1u, ep.ReadyListSize());
-  ep.SetFDReady(pipe_fds[1], EPOLLOUT);
-  EXPECT_TRUE(ep.IsFDReady(pipe_fds[0]));
-  EXPECT_TRUE(ep.IsFDReady(pipe_fds[1]));
-  EXPECT_EQ(2u, ep.ReadyListSize());
-
-  // Now check that SetFDNotReady doesn't affect other fds
-  ep.SetFDNotReady(pipe_fds[0]);
-  EXPECT_FALSE(ep.IsFDReady(pipe_fds[0]));
-  EXPECT_TRUE(ep.IsFDReady(pipe_fds[1]));
-  EXPECT_EQ(1u, ep.ReadyListSize());
-
-  ep.UnregisterFD(pipe_fds[0]);
-  ep.UnregisterFD(pipe_fds[1]);
-  EXPECT_EQ(0u, ep.ReadyListSize());
-
-  // Now try adding them when they are not registered, and it shouldn't work.
-  ep.SetFDReady(pipe_fds[0], EPOLLIN);
-  EXPECT_FALSE(ep.IsFDReady(pipe_fds[0]));
-  EXPECT_EQ(0u, ep.ReadyListSize());
-
-  close(pipe_fds[0]);
-  close(pipe_fds[1]);
-}
-
-class EPSWaitThread : public EpollThread {
- public:
-  explicit EPSWaitThread(SimpleEpollServer* eps)
-      : EpollThread("EPSWait"), eps_(eps), done_(false) {}
-
-  void Run() override { eps_->WaitForEventsAndExecuteCallbacks(); }
-
-  bool done() { return done_; }
-
- private:
-  SimpleEpollServer* eps_;
-  bool done_;
-};
-
-TEST(EpollServerTest, TestWake) {
-  SimpleEpollServer eps;
-  eps.set_timeout_in_us(-1);
-  EPSWaitThread eps_thread(&eps);
-  eps_thread.Start();
-
-  EXPECT_FALSE(eps_thread.done());
-  eps.Wake();
-  eps_thread.Join();
-}
-
-class UnRegisterWhileProcessingCB : public EpollCallbackInterface {
- public:
-  explicit UnRegisterWhileProcessingCB(int fd) : eps_(nullptr), fd_(fd) {}
-
-  ~UnRegisterWhileProcessingCB() override {}
-
-  void OnShutdown(SimpleEpollServer* /*eps*/, int /*fd*/) override {}
-
-  void set_epoll_server(SimpleEpollServer* eps) { eps_ = eps; }
-  void OnRegistration(SimpleEpollServer* /*eps*/, int /*fd*/,
-                      int /*event_mask*/) override {}
-  void OnModification(int /*fd*/, int /*event_mask*/) override {}
-  void OnEvent(int /*fd*/, EpollEvent* /*event*/) override {
-    // This should cause no problems.
-    eps_->UnregisterFD(fd_);
-  }
-  void OnUnregistration(int /*fd*/, bool /*replaced*/) override {}
-  std::string Name() const override { return "UnRegisterWhileProcessingCB"; }
-
- protected:
-  SimpleEpollServer* eps_;
-  int fd_;
-};
-
-class RegisterWhileProcessingCB : public EpollCallbackInterface {
- public:
-  RegisterWhileProcessingCB(int fd, EpollCallbackInterface* cb)
-      : eps_(nullptr), fd_(fd), cb_(cb) {}
-
-  ~RegisterWhileProcessingCB() override {}
-
-  void OnShutdown(SimpleEpollServer* /*eps*/, int /*fd*/) override {}
-
-  void set_epoll_server(SimpleEpollServer* eps) { eps_ = eps; }
-  void OnRegistration(SimpleEpollServer* /*eps*/, int /*fd*/,
-                      int /*event_mask*/) override {}
-  void OnModification(int /*fd*/, int /*event_mask*/) override {}
-  void OnEvent(int /*fd*/, EpollEvent* /*event*/) override {
-    // This should cause no problems.
-    eps_->RegisterFDForReadWrite(fd_, cb_);
-  }
-  void OnUnregistration(int /*fd*/, bool /*replaced*/) override {}
-  std::string Name() const override { return "RegisterWhileProcessingCB"; }
-
- protected:
-  SimpleEpollServer* eps_;
-  int fd_;
-  EpollCallbackInterface* cb_;
-};
-
-// Nothing bad should happen when we do this. We're -only-
-// testing that nothing bad occurs in this test.
-TEST(SimpleEpollServerTest, NothingBadWhenUnRegisteringFDWhileProcessingIt) {
-  UnRegisterWhileProcessingCB cb(0);
-  {
-    FakeSimpleEpollServer epoll_server;
-    cb.set_epoll_server(&epoll_server);
-    epoll_server.RegisterFDForReadWrite(0, &cb);
-    epoll_event ee;
-    ee.data.fd = 0;
-    epoll_server.AddEvent(0, ee);
-    epoll_server.AdvanceBy(1);
-    epoll_server.WaitForEventsAndExecuteCallbacks();
-  }
-}
-
-//
-// testing that nothing bad occurs in this test.
-TEST(SimpleEpollServerTest,
-     NoEventsDeliveredForFdsOfUnregisteredCBsWithReRegdFD) {
-  // events: fd0, fd1, fd2
-  // fd0 -> unreg fd2
-  // fd1 -> reg fd2
-  // fd2 -> no event should be seen
-  RecordingCB recorder_cb;
-  UnRegisterWhileProcessingCB unreg_cb(-3);
-  RegisterWhileProcessingCB reg_other_cb(-3, &recorder_cb);
-  {
-    FakeSimpleEpollServer epoll_server;
-    unreg_cb.set_epoll_server(&epoll_server);
-    reg_other_cb.set_epoll_server(&epoll_server);
-    epoll_server.RegisterFDForReadWrite(-1, &unreg_cb);
-    epoll_server.RegisterFDForReadWrite(-2, &reg_other_cb);
-    epoll_server.RegisterFDForReadWrite(-3, &recorder_cb);
-
-    epoll_event ee;
-    ee.events = EPOLLIN;  // asserted for all events for this test.
-
-    // Note that these events are in 'backwards' order in terms of time.
-    // Currently, the SimpleEpollServer code invokes the CBs from last delivered
-    // to first delivered, so this is to be sure that we invoke the CB for -1
-    // before -2, before -3.
-    ee.data.fd = -1;
-    epoll_server.AddEvent(2, ee);
-    ee.data.fd = -2;
-    epoll_server.AddEvent(1, ee);
-    ee.data.fd = -3;
-    epoll_server.AddEvent(0, ee);
-
-    epoll_server.AdvanceBy(5);
-    epoll_server.WaitForEventsAndExecuteCallbacks();
-  }
-
-  Recorder correct_recorder;
-  correct_recorder.Record(&recorder_cb, CREATION, 0, 0);
-  correct_recorder.Record(&recorder_cb, REGISTRATION, -3, EPOLLIN | EPOLLOUT);
-  correct_recorder.Record(&recorder_cb, UNREGISTRATION, -3, 0);
-  correct_recorder.Record(&recorder_cb, REGISTRATION, -3, EPOLLIN | EPOLLOUT);
-  correct_recorder.Record(&recorder_cb, SHUTDOWN, -3, 0);
-
-  EXPECT_TRUE(correct_recorder.IsEqual(recorder_cb.recorder()));
-}
-
-class ReRegWhileReadyListOnEvent : public EpollCallbackInterface {
- public:
-  explicit ReRegWhileReadyListOnEvent(int /*fd*/) : eps_(nullptr) {}
-
-  void OnShutdown(SimpleEpollServer* /*eps*/, int /*fd*/) override {}
-
-  void set_epoll_server(SimpleEpollServer* eps) { eps_ = eps; }
-  void OnRegistration(SimpleEpollServer* /*eps*/, int /*fd*/,
-                      int /*event_mask*/) override {}
-  void OnModification(int /*fd*/, int /*event_mask*/) override {}
-  void OnEvent(int fd, EpollEvent* /*event_mask*/) override {
-    // This should cause no problems.
-    eps_->UnregisterFD(fd);
-    eps_->RegisterFDForReadWrite(fd, this);
-    eps_->UnregisterFD(fd);
-  }
-  void OnUnregistration(int /*fd*/, bool /*replaced*/) override {}
-  std::string Name() const override { return "ReRegWhileReadyListOnEvent"; }
-
- protected:
-  SimpleEpollServer* eps_;
-};
-
-// Nothing bad should happen when we do this. We're -only-
-// testing that nothing bad occurs in this test.
-TEST(SimpleEpollServerTest,
-     NothingBadWhenReRegisteringFDWhileProcessingFromReadyList) {
-  ReRegWhileReadyListOnEvent cb(0);
-  {
-    FakeSimpleEpollServer epoll_server;
-    cb.set_epoll_server(&epoll_server);
-    epoll_server.RegisterFDForReadWrite(0, &cb);
-    epoll_event ee;
-    ee.data.fd = 0;
-    epoll_server.AddEvent(0, ee);
-    epoll_server.AdvanceBy(1);
-    epoll_server.WaitForEventsAndExecuteCallbacks();
-  }
-}
-
-class UnRegEverythingReadyListOnEvent : public EpollCallbackInterface {
- public:
-  UnRegEverythingReadyListOnEvent() : eps_(nullptr), fd_(0), fd_range_(0) {}
-
-  void set_fd(int fd) { fd_ = fd; }
-  void set_fd_range(int fd_range) { fd_range_ = fd_range; }
-  void set_num_called(int* num_called) { num_called_ = num_called; }
-
-  void OnShutdown(SimpleEpollServer* /*eps*/, int /*fd*/) override {}
-
-  void set_epoll_server(SimpleEpollServer* eps) { eps_ = eps; }
-  void OnRegistration(SimpleEpollServer* eps, int fd,
-                      int /*event_mask*/) override {
-    eps->SetFDReady(fd, EPOLLIN);
-  }
-  void OnModification(int /*fd*/, int /*event_mask*/) override {}
-  void OnEvent(int /*fd*/, EpollEvent* /*event*/) override {
-    // This should cause no problems.
-    CHECK(num_called_ != nullptr);
-    ++(*num_called_);
-    // Note that we're iterating from -fd_range + 1 -> 0.
-    // We do this because there is an FD installed into the
-    // epollserver somewhere in the low numbers.
-    // Using negative FD numbers (which are guaranteed to not
-    // exist in the epoll-server) ensures that we will not
-    // come in conflict with the preexisting FD.
-    for (int i = -fd_range_ + 1; i <= 0; ++i) {
-      eps_->UnregisterFD(i);
-    }
-  }
-  void OnUnregistration(int /*fd*/, bool /*replaced*/) override {}
-  std::string Name() const override {
-    return "UnRegEverythingReadyListOnEvent";
-  }
-
- protected:
-  SimpleEpollServer* eps_;
-  int fd_;
-  int fd_range_;
-  int* num_called_;
-};
-
-TEST(SimpleEpollServerTest,
-     NothingBadWhenUnRegisteredWhileProcessingFromReadyList) {
-  const size_t kNumCallbacks = 32u;
-  UnRegEverythingReadyListOnEvent callbacks[kNumCallbacks];
-  int num_called = 0;
-  {
-    FakeSimpleEpollServer epoll_server;
-    for (size_t i = 0; i < kNumCallbacks; ++i) {
-      callbacks[i].set_fd(-i);
-      callbacks[i].set_fd_range(kNumCallbacks);
-      callbacks[i].set_num_called(&num_called);
-      callbacks[i].set_epoll_server(&epoll_server);
-      epoll_server.RegisterFDForReadWrite(0, &callbacks[i]);
-      epoll_event ee;
-      ee.data.fd = -i;
-      epoll_server.AddEvent(0, ee);
-    }
-    epoll_server.AdvanceBy(1);
-    epoll_server.WaitForEventsAndExecuteCallbacks();
-    epoll_server.WaitForEventsAndExecuteCallbacks();
-  }
-  EXPECT_EQ(1, num_called);
-}
-
-TEST(SimpleEpollServerTest, TestThatVerifyReadyListWorksWithNothingInList) {
-  FakeSimpleEpollServer epoll_server;
-  epoll_server.VerifyReadyList();
-}
-
-TEST(SimpleEpollServerTest, TestThatVerifyReadyListWorksWithStuffInLists) {
-  FakeSimpleEpollServer epoll_server;
-  epoll_server.VerifyReadyList();
-}
-
-TEST(SimpleEpollServerTest,
-     ApproximateNowInUsAccurateOutideOfWaitForEventsAndExecuteCallbacks) {
-  FakeSimpleEpollServer epoll_server;
-  epoll_server.AdvanceBy(1232);
-  EXPECT_EQ(epoll_server.ApproximateNowInUsec(), epoll_server.NowInUsec());
-  epoll_server.AdvanceBy(1111);
-  EXPECT_EQ(epoll_server.ApproximateNowInUsec(), epoll_server.NowInUsec());
-}
-
-class ApproximateNowInUsecTestCB : public EpollCallbackInterface {
- public:
-  ApproximateNowInUsecTestCB() : feps_(nullptr), called_(false) {}
-
-  void OnRegistration(SimpleEpollServer* /*eps*/, int /*fd*/,
-                      int /*event_mask*/) override {}
-  void OnModification(int /*fd*/, int /*event_mask*/) override {}
-  void OnEvent(int /*fd*/, EpollEvent* /*event*/) override {
-    EXPECT_EQ(feps_->ApproximateNowInUsec(), feps_->NowInUsec());
-    feps_->AdvanceBy(1111);
-    EXPECT_EQ(1 * 1111 + feps_->ApproximateNowInUsec(), feps_->NowInUsec());
-    feps_->AdvanceBy(1111);
-    EXPECT_EQ(2 * 1111 + feps_->ApproximateNowInUsec(), feps_->NowInUsec());
-    called_ = true;
-  }
-  void OnUnregistration(int /*fd*/, bool /*replaced*/) override {}
-  void OnShutdown(SimpleEpollServer* /*eps*/, int /*fd*/) override {}
-  std::string Name() const override { return "ApproximateNowInUsecTestCB"; }
-
-  void set_fakeepollserver(FakeSimpleEpollServer* feps) { feps_ = feps; }
-  bool called() const { return called_; }
-
- protected:
-  FakeSimpleEpollServer* feps_;
-  bool called_;
-};
-
-TEST(SimpleEpollServerTest,
-     ApproximateNowInUsApproximateInsideOfWaitForEventsAndExecuteCallbacks) {
-  int dummy_fd = 11111;
-  ApproximateNowInUsecTestCB aniutcb;
-  {
-    FakeSimpleEpollServer epoll_server;
-    aniutcb.set_fakeepollserver(&epoll_server);
-
-    epoll_server.RegisterFD(dummy_fd, &aniutcb, EPOLLIN);
-    epoll_event ee;
-    ee.data.fd = dummy_fd;
-    ee.events = EPOLLIN;
-    epoll_server.AddEvent(10242, ee);
-    epoll_server.set_timeout_in_us(-1);
-    epoll_server.AdvanceByAndWaitForEventsAndExecuteCallbacks(20000);
-    EXPECT_TRUE(aniutcb.called());
-  }
-}
-
-// A mock epoll server that also simulates kernel delay in scheduling epoll
-// events.
-class FakeEpollServerWithDelay : public FakeSimpleEpollServer {
- public:
-  FakeEpollServerWithDelay() : FakeSimpleEpollServer(), delay(0) {}
-
-  int delay;
-
- protected:
-  int epoll_wait_impl(int epfd, struct epoll_event* events, int max_events,
-                      int timeout_in_ms) override {
-    int out = FakeSimpleEpollServer::epoll_wait_impl(epfd, events, max_events,
-                                                     timeout_in_ms);
-    AdvanceBy(delay);
-    return out;
-  }
-};
-
-// A callback that records the epoll event's delay.
-class RecordDelayOnEvent : public EpollCallbackInterface {
- public:
-  RecordDelayOnEvent() : last_delay(-1), eps_(nullptr) {}
-
-  ~RecordDelayOnEvent() override {}
-
-  void OnShutdown(SimpleEpollServer* /*eps*/, int /*fd*/) override {}
-
-  std::string Name() const override { return "RecordDelayOnEvent"; }
-
-  void set_epoll_server(SimpleEpollServer* eps) { eps_ = eps; }
-  void OnRegistration(SimpleEpollServer* /*eps*/, int /*fd*/,
-                      int /*event_mask*/) override {}
-  void OnModification(int /*fd*/, int /*event_mask*/) override {}
-  void OnEvent(int /*fd*/, EpollEvent* /*event*/) override {
-    last_delay = eps_->LastDelayInUsec();
-  }
-  void OnUnregistration(int /*fd*/, bool /*replaced*/) override {}
-
-  int64_t last_delay;
-
- protected:
-  SimpleEpollServer* eps_;
-};
-
-// Tests that an epoll callback sees the correct delay for its event when it
-// calls LastDelayInUsec().
-TEST(EpollServerTest, TestLastDelay) {
-  RecordDelayOnEvent cb;
-  FakeEpollServerWithDelay epoll_server;
-
-  cb.set_epoll_server(&epoll_server);
-
-  epoll_server.RegisterFDForReadWrite(0, &cb);
-  epoll_event ee;
-  ee.data.fd = 0;
-
-  // Inject delay, and confirm that it's reported.
-  epoll_server.set_timeout_in_us(5000);
-  epoll_server.delay = 6000;
-  epoll_server.AddEvent(0, ee);
-  epoll_server.AdvanceBy(1);
-  epoll_server.WaitForEventsAndExecuteCallbacks();
-  EXPECT_EQ(cb.last_delay, 1000);
-
-  // Fire an event before the timeout ends, and confirm that reported delay
-  // isn't negative.
-  epoll_server.set_timeout_in_us(5000);
-  epoll_server.delay = 0;
-  epoll_server.AddEvent(0, ee);
-  epoll_server.AdvanceBy(1);
-  epoll_server.WaitForEventsAndExecuteCallbacks();
-  EXPECT_EQ(cb.last_delay, 0);
-
-  // Wait forever until an event fires, and confirm there's no reported delay.
-  epoll_server.set_timeout_in_us(-1);
-  epoll_server.delay = 6000;
-  epoll_server.AddEvent(0, ee);
-  epoll_server.AdvanceBy(1);
-  epoll_server.WaitForEventsAndExecuteCallbacks();
-  EXPECT_EQ(cb.last_delay, 0);
-}
-
-TEST(SimpleEpollServerAlarmTest, TestShutdown) {
-  std::unique_ptr<SimpleEpollServer> eps(new SimpleEpollServer);
-  EpollAlarm alarm1;
-  EpollAlarm alarm2;
-
-  eps->RegisterAlarmApproximateDelta(10000000, &alarm1);
-  eps->RegisterAlarmApproximateDelta(10000000, &alarm2);
-
-  alarm2.UnregisterIfRegistered();
-  EXPECT_FALSE(alarm2.registered());
-  eps = nullptr;
-
-  EXPECT_FALSE(alarm1.registered());
-}
-
-TEST(SimpleEpollServerAlarmTest, TestUnregister) {
-  SimpleEpollServer eps;
-  EpollAlarm alarm;
-
-  eps.RegisterAlarmApproximateDelta(10000000, &alarm);
-  EXPECT_TRUE(alarm.registered());
-
-  alarm.UnregisterIfRegistered();
-  EXPECT_FALSE(alarm.registered());
-
-  alarm.UnregisterIfRegistered();
-  EXPECT_FALSE(alarm.registered());
-}
-
-TEST(SimpleEpollServerAlarmTest, TestUnregisterOnDestruction) {
-  EpollTestServer eps;
-  std::unique_ptr<EpollAlarm> alarm(new EpollAlarm());
-  EpollAlarm* alarm_ptr = alarm.get();
-
-  eps.RegisterAlarmApproximateDelta(10000000, alarm.get());
-  EXPECT_TRUE(eps.ContainsAlarm(alarm_ptr));
-  alarm = nullptr;
-  EXPECT_EQ(0u, eps.GetNumPendingAlarmsForTest());
-}
-
-TEST(SimpleEpollServerAlarmTest, TestUnregisterOnAlarm) {
-  EpollTestServer eps;
-  EpollAlarm alarm;
-
-  eps.RegisterAlarmApproximateDelta(1, &alarm);
-  EXPECT_TRUE(eps.ContainsAlarm(&alarm));
-
-  while (alarm.registered()) {
-    eps.WaitForEventsAndExecuteCallbacks();
-  }
-  EXPECT_FALSE(eps.ContainsAlarm(&alarm));
-}
-
-TEST(SimpleEpollServerAlarmTest, TestReregisterAlarm) {
-  EpollTestAlarms ep;
-
-  EpollAlarm alarm;
-  ep.set_time(1000);
-  ep.RegisterAlarm(5000, &alarm);
-
-  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
-  alarm.ReregisterAlarm(6000);
-  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
-
-  ep.set_time(5000);
-  ep.set_timeout_in_us(0);
-  ep.CallAndReregisterAlarmEvents();
-  EXPECT_EQ(1u, ep.GetNumPendingAlarmsForTest());
-
-  ep.set_time(6000);
-  ep.CallAndReregisterAlarmEvents();
-  EXPECT_EQ(0u, ep.GetNumPendingAlarmsForTest());
-}
-
-TEST(SimpleEpollServerAlarmTest, TestThatSameAlarmCanNotBeRegisteredTwice) {
-  TestAlarm alarm;
-  SimpleEpollServer epoll_server;
-  epoll_server.RegisterAlarm(1, &alarm);
-  EXPECT_EPOLL_BUG(epoll_server.RegisterAlarm(1, &alarm),
-                   "Alarm already exists");
-}
-
-}  // namespace
-
-}  // namespace test
-
-}  // namespace epoll_server
