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
