Project import generated by Copybara.

PiperOrigin-RevId: 243658601
Change-Id: I2522d468d82c86f8f222cf0e70114d6a9ca2b78c
diff --git a/epoll_server/fake_simple_epoll_server.cc b/epoll_server/fake_simple_epoll_server.cc
new file mode 100644
index 0000000..7e55945
--- /dev/null
+++ b/epoll_server/fake_simple_epoll_server.cc
@@ -0,0 +1,56 @@
+// 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 "net/third_party/quiche/src/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/epoll_server/fake_simple_epoll_server.h b/epoll_server/fake_simple_epoll_server.h
new file mode 100644
index 0000000..d245743
--- /dev/null
+++ b/epoll_server/fake_simple_epoll_server.h
@@ -0,0 +1,113 @@
+// 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 <unordered_map>
+#include <unordered_set>
+
+#include "net/third_party/quiche/src/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::unordered_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/epoll_server/platform/api/epoll_address_test_utils.h b/epoll_server/platform/api/epoll_address_test_utils.h
new file mode 100644
index 0000000..ae87ded
--- /dev/null
+++ b/epoll_server/platform/api/epoll_address_test_utils.h
@@ -0,0 +1,16 @@
+// 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 "net/epoll_server/platform/impl/epoll_address_test_utils_impl.h"
+
+namespace epoll_server {
+
+int AddressFamilyUnderTest() { return AddressFamilyUnderTestImpl(); }
+
+}  // namespace epoll_server
+
+#endif  // QUICHE_EPOLL_SERVER_PLATFORM_API_EPOLL_ADDRESS_TEST_UTILS_H_
diff --git a/epoll_server/platform/api/epoll_bug.h b/epoll_server/platform/api/epoll_bug.h
new file mode 100644
index 0000000..d90c427
--- /dev/null
+++ b/epoll_server/platform/api/epoll_bug.h
@@ -0,0 +1,12 @@
+// 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 "net/epoll_server/platform/impl/epoll_bug_impl.h"
+
+#define EPOLL_BUG EPOLL_BUG_IMPL
+
+#endif  // QUICHE_EPOLL_SERVER_PLATFORM_API_EPOLL_BUG_H_
diff --git a/epoll_server/platform/api/epoll_expect_bug.h b/epoll_server/platform/api/epoll_expect_bug.h
new file mode 100644
index 0000000..a7795c6
--- /dev/null
+++ b/epoll_server/platform/api/epoll_expect_bug.h
@@ -0,0 +1,12 @@
+// 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 "net/epoll_server/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/epoll_server/platform/api/epoll_logging.h b/epoll_server/platform/api/epoll_logging.h
new file mode 100644
index 0000000..bcd9b96
--- /dev/null
+++ b/epoll_server/platform/api/epoll_logging.h
@@ -0,0 +1,19 @@
+// 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 "net/epoll_server/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/epoll_server/platform/api/epoll_test.h b/epoll_server/platform/api/epoll_test.h
new file mode 100644
index 0000000..e5a0524
--- /dev/null
+++ b/epoll_server/platform/api/epoll_test.h
@@ -0,0 +1,11 @@
+// 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 "net/epoll_server/platform/impl/epoll_test_impl.h"
+#define EpollTest EpollTestImpl
+
+#endif  // QUICHE_EPOLL_SERVER_PLATFORM_API_EPOLL_TEST_H_
diff --git a/epoll_server/platform/api/epoll_thread.h b/epoll_server/platform/api/epoll_thread.h
new file mode 100644
index 0000000..a41dd28
--- /dev/null
+++ b/epoll_server/platform/api/epoll_thread.h
@@ -0,0 +1,27 @@
+// 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 "net/epoll_server/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/epoll_server/platform/api/epoll_time.h b/epoll_server/platform/api/epoll_time.h
new file mode 100644
index 0000000..9fefaa7
--- /dev/null
+++ b/epoll_server/platform/api/epoll_time.h
@@ -0,0 +1,16 @@
+// 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_TIME_H_
+#define QUICHE_EPOLL_SERVER_PLATFORM_API_EPOLL_TIME_H_
+
+#include "net/epoll_server/platform/impl/epoll_time_impl.h"
+
+namespace epoll_server {
+
+int64_t WallTimeNowInUsec() { return WallTimeNowInUsecImpl(); }
+
+}  // namespace epoll_server
+
+#endif  // QUICHE_EPOLL_SERVER_PLATFORM_API_EPOLL_TIME_H_
diff --git a/epoll_server/simple_epoll_server.cc b/epoll_server/simple_epoll_server.cc
new file mode 100644
index 0000000..0117542
--- /dev/null
+++ b/epoll_server/simple_epoll_server.cc
@@ -0,0 +1,812 @@
+// 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 "net/third_party/quiche/src/epoll_server/simple_epoll_server.h"
+
+#include <errno.h>   // for errno and strerror_r
+#include <stdlib.h>  // for abort
+#include <unistd.h>  // For read, pipe, close and write.
+
+#include <algorithm>
+#include <utility>
+
+#include "net/third_party/quiche/src/epoll_server/platform/api/epoll_bug.h"
+#include "net/third_party/quiche/src/epoll_server/platform/api/epoll_time.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 << "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 WallTimeNowInUsec(); }
+
+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/epoll_server/simple_epoll_server.h b/epoll_server/simple_epoll_server.h
new file mode 100644
index 0000000..78b6d79
--- /dev/null
+++ b/epoll_server/simple_epoll_server.h
@@ -0,0 +1,1050 @@
+// 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_H_
+#define QUICHE_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 "net/third_party/quiche/src/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_; }
+
+  // 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_H_
diff --git a/epoll_server/simple_epoll_server_test.cc b/epoll_server/simple_epoll_server_test.cc
new file mode 100644
index 0000000..140eb2b
--- /dev/null
+++ b/epoll_server/simple_epoll_server_test.cc
@@ -0,0 +1,2517 @@
+// 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 "net/third_party/quiche/src/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 <hash_map>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "net/third_party/quiche/src/epoll_server/fake_simple_epoll_server.h"
+#include "net/third_party/quiche/src/epoll_server/platform/api/epoll_address_test_utils.h"
+#include "net/third_party/quiche/src/epoll_server/platform/api/epoll_expect_bug.h"
+#include "net/third_party/quiche/src/epoll_server/platform/api/epoll_test.h"
+#include "net/third_party/quiche/src/epoll_server/platform/api/epoll_thread.h"
+#include "net/third_party/quiche/src/epoll_server/platform/api/epoll_time.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
+};
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+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];
+      read(fd, &buf, kLength);
+    }
+  }
+
+  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);
+  }
+
+  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) {
+      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(2, records->size());
+
+  // Call handle event and make sure something was recorded.
+  ep()->HandleEvent(fd(), EPOLLOUT);
+  ep()->CallReadyListCallbacks();
+  EXPECT_EQ(3, records->size());
+
+  // Call handle event and make sure something was recorded.
+  ep()->HandleEvent(fd(), EPOLLIN | O_NONBLOCK);
+  ep()->CallReadyListCallbacks();
+  EXPECT_EQ(4, 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) {
+  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 __gnu_cxx::hash_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(1, ep.GetNumPendingAlarmsForTest());
+  WaitForAlarm(&ep, alarm);
+  EXPECT_TRUE(alarm.was_called());
+  EXPECT_EQ(0, 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(1, 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(0, 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(1, ep.GetNumPendingAlarmsForTest());
+  WaitForAlarm(&ep, alarm);
+  EXPECT_TRUE(alarm.was_called());
+  EXPECT_EQ(0, ep.GetNumPendingAlarmsForTest());
+  alarm.Reset();
+  int64_t first_now = ep.ApproximateNowInUsec();
+  EXPECT_LT(0, 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(1, 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(0, 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(1, ep.GetNumPendingAlarmsForTest());
+  WaitForAlarm(&ep, alarm);
+  EXPECT_TRUE(alarm.was_called());
+  EXPECT_EQ(0, 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(2, 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(1, 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(2, 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(0, 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(1, 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(1, 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(0, 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(1, 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(1, 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(0, 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(1, ep.GetNumPendingAlarmsForTest());
+  ep.WaitForEventsAndExecuteCallbacks();
+  EXPECT_TRUE(alarm.was_called());
+  EXPECT_EQ(0, 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(1, ep.GetNumPendingAlarmsForTest());
+  EXPECT_TRUE(alarm2.onunregistration_called());
+
+  if (alarm1.get_token(&temptok)) {
+    ep.UnregisterAlarm(temptok);
+  }
+  EXPECT_EQ(0, 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(1, ep.GetNumPendingAlarmsForTest());
+  ASSERT_TRUE(alarm.get_token(&token));
+  ep.ReregisterAlarm(token, 6000);
+  EXPECT_EQ(1, 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(1, 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(2, 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(2, 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(2, 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(3, 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(4, 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(2, 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(2, records_one->size());
+  EXPECT_EQ(2, records_two->size());
+
+  write(pipe_one[1], &data, 1);
+  ep.WaitForEventsAndExecuteCallbacks();
+  EXPECT_EQ(3, records_one->size());
+  EXPECT_EQ(2, records_two->size());
+
+
+  write(pipe_two[1], &data, 1);
+  ep.WaitForEventsAndExecuteCallbacks();
+  EXPECT_EQ(3, records_one->size());
+  EXPECT_EQ(3, records_two->size());
+
+  write(pipe_one[1], &data, 1);
+  write(pipe_two[1], &data, 1);
+  ep.WaitForEventsAndExecuteCallbacks();
+  EXPECT_EQ(4, records_one->size());
+  EXPECT_EQ(4, 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 {}
+
+  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(2, 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(3, records->size());
+  EXPECT_FALSE(alarm.was_called());
+  ep.RegisterAlarm(WallTimeNowInUsec() + 1000, &alarm);
+  WaitForAlarm(&ep, alarm);
+  EXPECT_EQ(3, 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(4, 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);
+  }
+
+  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) {
+    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) {
+        PLOG(FATAL) << "write() failed";
+      }
+      close(writer_pipe);
+
+      _exit(0);
+    }
+    case -1:
+      PLOG(FATAL) << "fork() failed";
+      break;
+    default: {  // Parent will receive message.
+      close(writer_pipe);
+      auto ep = absl::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 = absl::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_ ? 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);
+  }
+
+  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(1, ep.ReadyListSize());
+  ep.SetFDReady(pipe_fds[1], EPOLLOUT);
+  EXPECT_TRUE(ep.IsFDReady(pipe_fds[0]));
+  EXPECT_TRUE(ep.IsFDReady(pipe_fds[1]));
+  EXPECT_EQ(2, 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(1, ep.ReadyListSize());
+
+  ep.UnregisterFD(pipe_fds[0]);
+  ep.UnregisterFD(pipe_fds[1]);
+  EXPECT_EQ(0, 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(0, 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 {}
+  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 {}
+  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) override {
+    // This should cause no problems.
+    eps_->UnregisterFD(fd);
+    eps_->RegisterFDForReadWrite(fd, this);
+    eps_->UnregisterFD(fd);
+  }
+  void OnUnregistration(int fd, bool replaced) override {}
+  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 {}
+  string Name() const override { return "UnRegEverythingReadyListOnEvent"; }
+
+ protected:
+  SimpleEpollServer* eps_;
+  int fd_;
+  int fd_range_;
+  int* num_called_;
+};
+
+TEST(SimpleEpollServerTest,
+     NothingBadWhenUnRegisteredWhileProcessingFromReadyList) {
+  UnRegEverythingReadyListOnEvent callbacks[32];
+  int num_called = 0;
+  {
+    FakeSimpleEpollServer epoll_server;
+    for (size_t i = 0; i < ABSL_ARRAYSIZE(callbacks); ++i) {
+      callbacks[i].set_fd(-i);
+      callbacks[i].set_fd_range(ABSL_ARRAYSIZE(callbacks));
+      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 {}
+  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 {}
+
+  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(0, 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(1, ep.GetNumPendingAlarmsForTest());
+  alarm.ReregisterAlarm(6000);
+  EXPECT_EQ(1, ep.GetNumPendingAlarmsForTest());
+
+  ep.set_time(5000);
+  ep.set_timeout_in_us(0);
+  ep.CallAndReregisterAlarmEvents();
+  EXPECT_EQ(1, ep.GetNumPendingAlarmsForTest());
+
+  ep.set_time(6000);
+  ep.CallAndReregisterAlarmEvents();
+  EXPECT_EQ(0, 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