// 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 "epoll_server/platform/api/epoll_export.h"
#include "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 EPOLL_EXPORT_PRIVATE SimpleEpollServer {
 public:
  typedef EpollAlarmCallbackInterface AlarmCB;
  typedef EpollCallbackInterface CB;

  typedef std::multimap<int64_t, AlarmCB*> TimeToAlarmCBMap;
  typedef TimeToAlarmCBMap::iterator AlarmRegToken;

  // Summary:
  //   Constructor:
  //    By default, we don't wait any amount of time for events, and
  //    we suggest to the epoll-system that we're going to use on-the-order
  //    of 1024 FDs.
  SimpleEpollServer();

  SimpleEpollServer(const SimpleEpollServer&) = delete;
  SimpleEpollServer operator=(const SimpleEpollServer&) = delete;

  ////////////////////////////////////////

  // Destructor
  virtual ~SimpleEpollServer();

  ////////////////////////////////////////

  // Summary
  //   Register a callback to be called whenever an event contained
  //   in the set of events included in event_mask occurs on the
  //   file-descriptor 'fd'
  //
  //   Note that only one callback is allowed to be registered for
  //   any specific file-decriptor.
  //
  //   If a callback is registered for a file-descriptor which has already
  //   been registered, then the previous callback is unregistered with
  //   the 'replaced' flag set to true. I.e. the previous callback's
  //   OnUnregistration() function is called like so:
  //      OnUnregistration(fd, true);
  //
  //  The epoll server does NOT take on ownership of the callback: the callback
  //  creator is responsible for managing that memory.
  //
  // Args:
  //   fd - a valid file-descriptor
  //   cb - an instance of a subclass of EpollCallbackInterface
  //   event_mask - a combination of (EPOLLOUT, EPOLLIN.. etc) indicating
  //                the events for which the callback would like to be
  //                called.
  virtual void RegisterFD(int fd, CB* cb, int event_mask);

  ////////////////////////////////////////

  // Summary:
  //   A shortcut for RegisterFD which sets things up such that the
  //   callback is called when 'fd' is available for writing.
  // Args:
  //   fd - a valid file-descriptor
  //   cb - an instance of a subclass of EpollCallbackInterface
  virtual void RegisterFDForWrite(int fd, CB* cb);

  ////////////////////////////////////////

  // Summary:
  //   A shortcut for RegisterFD which sets things up such that the
  //   callback is called when 'fd' is available for reading or writing.
  // Args:
  //   fd - a valid file-descriptor
  //   cb - an instance of a subclass of EpollCallbackInterface
  virtual void RegisterFDForReadWrite(int fd, CB* cb);

  ////////////////////////////////////////

  // Summary:
  //   A shortcut for RegisterFD which sets things up such that the
  //   callback is called when 'fd' is available for reading.
  // Args:
  //   fd - a valid file-descriptor
  //   cb - an instance of a subclass of EpollCallbackInterface
  virtual void RegisterFDForRead(int fd, CB* cb);

  ////////////////////////////////////////

  // Summary:
  //   Removes the FD and the associated callback from the pollserver.
  //   If the callback is registered with other FDs, they will continue
  //   to be processed using the callback without modification.
  //   If the file-descriptor specified is not registered in the
  //   epoll_server, then nothing happens as a result of this call.
  // Args:
  //   fd - the file-descriptor which should no-longer be monitored.
  virtual void UnregisterFD(int fd);

  ////////////////////////////////////////

  // Summary:
  //   Modifies the event mask for the file-descriptor, replacing
  //   the old event_mask with the new one specified here.
  //   If the file-descriptor specified is not registered in the
  //   epoll_server, then nothing happens as a result of this call.
  // Args:
  //   fd - the fd whose event mask should be modified.
  //   event_mask - the new event mask.
  virtual void ModifyCallback(int fd, int event_mask);

  ////////////////////////////////////////

  // Summary:
  //   Modifies the event mask for the file-descriptor such that we
  //   no longer request events when 'fd' is readable.
  //   If the file-descriptor specified is not registered in the
  //   epoll_server, then nothing happens as a result of this call.
  // Args:
  //   fd - the fd whose event mask should be modified.
  virtual void StopRead(int fd);

  ////////////////////////////////////////

  // Summary:
  //   Modifies the event mask for the file-descriptor such that we
  //   request events when 'fd' is readable.
  //   If the file-descriptor specified is not registered in the
  //   epoll_server, then nothing happens as a result of this call.
  // Args:
  //   fd - the fd whose event mask should be modified.
  virtual void StartRead(int fd);

  ////////////////////////////////////////

  // Summary:
  //   Modifies the event mask for the file-descriptor such that we
  //   no longer request events when 'fd' is writable.
  //   If the file-descriptor specified is not registered in the
  //   epoll_server, then nothing happens as a result of this call.
  // Args:
  //   fd - the fd whose event mask should be modified.
  virtual void StopWrite(int fd);

  ////////////////////////////////////////

  // Summary:
  //   Modifies the event mask for the file-descriptor such that we
  //   request events when 'fd' is writable.
  //   If the file-descriptor specified is not registered in the
  //   epoll_server, then nothing happens as a result of this call.
  // Args:
  //   fd - the fd whose event mask should be modified.
  virtual void StartWrite(int fd);

  ////////////////////////////////////////

  // Summary:
  //   Looks up the callback associated with the file-descriptor 'fd'.
  //   If a callback is associated with this file-descriptor, then
  //   it's OnEvent() method is called with the file-descriptor 'fd',
  //   and event_mask 'event_mask'
  //
  //   If no callback is registered for this file-descriptor, nothing
  //   will happen as a result of this call.
  //
  //   This function is used internally by the SimpleEpollServer, but is
  //   available publicly so that events might be 'faked'. Calling
  //   this function with an fd and event_mask is equivalent (as far
  //   as the callback is concerned) to having a real event generated
  //   by epoll (except, of course, that read(), etc won't necessarily
  //   be able to read anything)
  // Args:
  //   fd - the file-descriptor on which an event has occurred.
  //   event_mask - a bitmask representing the events which have occurred
  //                on/for this fd. This bitmask is composed of
  //                POLLIN, POLLOUT, etc.
  //
  void HandleEvent(int fd, int event_mask);

  // Summary:
  //   Call this when you want the pollserver to
  //   wait for events and execute the callbacks associated with
  //   the file-descriptors on which those events have occurred.
  //   Depending on the value of timeout_in_us_, this may or may
  //   not return immediately. Please reference the set_timeout()
  //   function for the specific behaviour.
  virtual void WaitForEventsAndExecuteCallbacks();

  // Summary:
  //   When an fd is registered to use edge trigger notification, the ready
  //   list can be used to simulate level trigger semantics. Edge trigger
  //   registration doesn't send an initial event, and only rising edge (going
  //   from blocked to unblocked) events are sent. A callback can put itself on
  //   the ready list by calling SetFDReady() after calling RegisterFD(). The
  //   OnEvent method of all callbacks associated with the fds on the ready
  //   list will be called immediately after processing the events returned by
  //   epoll_wait(). The fd is removed from the ready list before the
  //   callback's OnEvent() method is invoked. To stay on the ready list, the
  //   OnEvent() (or some function in that call chain) must call SetFDReady
  //   again. When a fd is unregistered using UnregisterFD(), the fd is
  //   automatically removed from the ready list.
  //
  //   When the callback for a edge triggered fd hits the falling edge (about
  //   to block, either because of it got an EAGAIN, or had a short read/write
  //   operation), it should remove itself from the ready list using
  //   SetFDNotReady() (since OnEvent cannot distinguish between invocation
  //   from the ready list vs from a normal epoll event). All four ready list
  //   methods are safe to be called  within the context of the callbacks.
  //
  //   Since the ready list invokes EpollCallbackInterface::OnEvent, only fds
  //   that are registered with the SimpleEpollServer will be put on the ready
  //   list. SetFDReady() and SetFDNotReady() will do nothing if the
  //   SimpleEpollServer doesn't know about the fd passed in.
  //
  //   Since the ready list cannot reliably determine proper set of events
  //   which should be sent to the callback, SetFDReady() requests the caller
  //   to provide the ready list with the event mask, which will be used later
  //   when OnEvent() is invoked by the ready list. Hence, the event_mask
  //   passedto SetFDReady() does not affect the actual epoll registration of
  //   the fd with the kernel. If a fd is already put on the ready list, and
  //   SetFDReady() is called again for that fd with a different event_mask,
  //   the event_mask will be updated.
  virtual void SetFDReady(int fd, int events_to_fake);

  virtual void SetFDNotReady(int fd);

  // Summary:
  //   IsFDReady(), ReadyListSize(), and VerifyReadyList are intended as
  //   debugging tools and for writing unit tests.
  //   ISFDReady() returns whether a fd is in the ready list.
  //   ReadyListSize() returns the number of fds on the ready list.
  //   VerifyReadyList() checks the consistency of internal data structure. It
  //   will CHECK if it finds an error.
  virtual bool IsFDReady(int fd) const;

  size_t ReadyListSize() const { return ready_list_size_; }

  void VerifyReadyList() const;

  ////////////////////////////////////////

  // Summary:
  //   Registers an alarm 'ac' to go off at time 'timeout_time_in_us'.
  //   If the callback returns a positive number from its OnAlarm() function,
  //   then the callback will be re-registered at that time, else the alarm
  //   owner is responsible for freeing up memory.
  //
  //   Important: A give AlarmCB* can not be registered again if it is already
  //    registered. If a user wants to register a callback again it should first
  //    unregister the previous callback before calling RegisterAlarm again.
  // Args:
  //   timeout_time_in_us - the absolute time at which the alarm should go off
  //   ac - the alarm which will be called.
  virtual void RegisterAlarm(int64_t timeout_time_in_us, AlarmCB* ac);

  // Summary:
  //   Registers an alarm 'ac' to go off at time: (ApproximateNowInUs() +
  //   delta_in_us). While this is somewhat less accurate (see the description
  //   for ApproximateNowInUs() to see how 'approximate'), the error is never
  //   worse than the amount of time it takes to process all events in one
  //   WaitForEvents.  As with 'RegisterAlarm()', if the callback returns a
  //   positive number from its OnAlarm() function, then the callback will be
  //   re-registered at that time, else the alarm owner is responsible for
  //   freeing up memory.
  //   Note that this function is purely a convienence. The
  //   same thing may be accomplished by using RegisterAlarm with
  //   ApproximateNowInUs() directly.
  //
  //   Important: A give AlarmCB* can not be registered again if it is already
  //    registered. If a user wants to register a callback again it should first
  //    unregister the previous callback before calling RegisterAlarm again.
  // Args:
  //   delta_in_us - the delta in microseconds from the ApproximateTimeInUs() at
  //                 which point the alarm should go off.
  //   ac - the alarm which will be called.
  void RegisterAlarmApproximateDelta(int64_t delta_in_us, AlarmCB* ac) {
    RegisterAlarm(ApproximateNowInUsec() + delta_in_us, ac);
  }

  ////////////////////////////////////////

  // Summary:
  //   Unregister  the alarm referred to by iterator_token; Callers should
  //   be warned that a token may have become already invalid when OnAlarm()
  //   is called, was unregistered, or OnShutdown was called on that alarm.
  // Args:
  //    iterator_token - iterator to the alarm callback to unregister.
  virtual void UnregisterAlarm(
      const SimpleEpollServer::AlarmRegToken& iterator_token);

  virtual SimpleEpollServer::AlarmRegToken ReregisterAlarm(
      SimpleEpollServer::AlarmRegToken iterator_token,
      int64_t timeout_time_in_us);

  ////////////////////////////////////////

  // Summary:
  //   returns the number of file-descriptors registered in this
  //   SimpleEpollServer.
  // Returns:
  //   number of FDs registered (discounting the internal pipe used for Wake)
  virtual int NumFDsRegistered() const;

  // Summary:
  //   Force the epoll server to wake up (by writing to an internal pipe).
  virtual void Wake();

  // Summary:
  //   Wrapper around WallTimer's NowInUsec.  We do this so that we can test
  //   SimpleEpollServer without using the system clock (and can avoid the
  //   flakiness that would ensue)
  // Returns:
  //   the current time as number of microseconds since the Unix epoch.
  virtual int64_t NowInUsec() const;

  // Summary:
  //   Since calling NowInUsec() many thousands of times per
  //   WaitForEventsAndExecuteCallbacks function call is, to say the least,
  //   inefficient, we allow users to use an approximate time instead. The
  //   time returned from this function is as accurate as NowInUsec() when
  //   WaitForEventsAndExecuteCallbacks is not an ancestor of the caller's
  //   callstack.
  //   However, when WaitForEventsAndExecuteCallbacks -is- an ancestor, then
  //   this function returns the time at which the
  //   WaitForEventsAndExecuteCallbacks function started to process events or
  //   alarms.
  //
  //   Essentially, this function makes available a fast and mostly accurate
  //   mechanism for getting the time for any function handling an event or
  //   alarm. When functions which are not handling callbacks or alarms call
  //   this function, they get the slow and "absolutely" accurate time.
  //
  //   Users should be encouraged to use this function.
  // Returns:
  //   the "approximate" current time as number of microseconds since the Unix
  //   epoch.
  virtual int64_t ApproximateNowInUsec() const;

  static std::string EventMaskToString(int event_mask);

  // Summary:
  //   Logs the state of the epoll server with EPOLL_LOG(ERROR).
  void LogStateOnCrash();

  // Summary:
  //   Set the timeout to the value specified.
  //   If the timeout is set to a negative number,
  //      WaitForEventsAndExecuteCallbacks() will only return when an event has
  //      occurred
  //   If the timeout is set to zero,
  //      WaitForEventsAndExecuteCallbacks() will return immediately
  //   If the timeout is set to a positive number,
  //      WaitForEventsAndExecuteCallbacks() will return when an event has
  //      occurred, or when timeout_in_us microseconds has elapsed, whichever
  //      is first.
  //  Args:
  //    timeout_in_us - value specified depending on behaviour desired.
  //                    See above.
  void set_timeout_in_us(int64_t timeout_in_us) {
    timeout_in_us_ = timeout_in_us;
  }

  ////////////////////////////////////////

  // Summary:
  //   Accessor for the current value of timeout_in_us.
  int timeout_in_us_for_test() const { return timeout_in_us_; }

  // Summary:
  // Returns true when the SimpleEpollServer() is being destroyed.
  bool in_shutdown() const { return in_shutdown_; }
  bool ShutdownCalled() const { return in_shutdown(); }

  // Compatibility stub.
  void Shutdown() {}

  // Summary:
  //   A function for implementing the ready list. It invokes OnEvent for each
  //   of the fd in the ready list, and takes care of adding them back to the
  //   ready list if the callback requests it (by checking that out_ready_mask
  //   is non-zero).
  void CallReadyListCallbacks();

  int64_t LastDelayInUsec() const { return last_delay_in_usec_; }

 protected:
  virtual void SetNonblocking(int fd);

  // This exists here so that we can override this function in unittests
  // in order to make effective mock SimpleEpollServer objects.
  virtual int epoll_wait_impl(int epfd, struct epoll_event* events,
                              int max_events, int timeout_in_ms);

  // this struct is used internally, and is never used by anything external
  // to this class. Some of its members are declared mutable to get around the
  // restriction imposed by hash_set. Since hash_set knows nothing about the
  // objects it stores, it has to assume that every bit of the object is used
  // in the hash function and equal_to comparison. Thus hash_set::iterator is a
  // const iterator. In this case, the only thing that must stay constant is
  // fd. Everything else are just along for the ride and changing them doesn't
  // compromise the hash_set integrity.
  struct CBAndEventMask {
    CBAndEventMask()
        : cb(NULL),
          fd(-1),
          event_mask(0),
          events_asserted(0),
          events_to_fake(0),
          in_use(false) {
      entry.le_next = NULL;
      entry.le_prev = NULL;
    }

    CBAndEventMask(EpollCallbackInterface* cb, int event_mask, int fd)
        : cb(cb),
          fd(fd),
          event_mask(event_mask),
          events_asserted(0),
          events_to_fake(0),
          in_use(false) {
      entry.le_next = NULL;
      entry.le_prev = NULL;
    }

    // Required operator for hash_set. Normally operator== should be a free
    // standing function. However, since CBAndEventMask is a protected type and
    // it will never be a base class, it makes no difference.
    bool operator==(const CBAndEventMask& cb_and_mask) const {
      return fd == cb_and_mask.fd;
    }
    // A callback. If the fd is unregistered inside the callchain of OnEvent,
    // the cb will be set to NULL.
    mutable EpollCallbackInterface* cb;

    mutable LIST_ENTRY(CBAndEventMask) entry;
    // file descriptor registered with the epoll server.
    int fd;
    // the current event_mask registered for this callback.
    mutable int event_mask;
    // the event_mask that was returned by epoll
    mutable int events_asserted;
    // the event_mask for the ready list to use to call OnEvent.
    mutable int events_to_fake;
    // toggle around calls to OnEvent to tell UnregisterFD to not erase the
    // iterator because HandleEvent is using it.
    mutable bool in_use;
  };

  // Custom hash function to be used by hash_set.
  struct CBAndEventMaskHash {
    size_t operator()(const CBAndEventMask& cb_and_eventmask) const {
      return static_cast<size_t>(cb_and_eventmask.fd);
    }
  };

  using FDToCBMap = std::unordered_set<CBAndEventMask, CBAndEventMaskHash>;

  // the following four functions are OS-specific, and are likely
  // to be changed in a subclass if the poll/select method is changed
  // from epoll.

  // Summary:
  //   Deletes a file-descriptor from the set of FDs that should be
  //   monitored with epoll.
  //   Note that this only deals with modifying data relating -directly-
  //   with the epoll call-- it does not modify any data within the
  //   epoll_server.
  // Args:
  //   fd - the file descriptor to-be-removed from the monitoring set
  virtual void DelFD(int fd) const;

  ////////////////////////////////////////

  // Summary:
  //   Adds a file-descriptor to the set of FDs that should be
  //   monitored with epoll.
  //   Note that this only deals with modifying data relating -directly-
  //   with the epoll call.
  // Args:
  //   fd - the file descriptor to-be-added to the monitoring set
  //   event_mask - the event mask (consisting of EPOLLIN, EPOLLOUT, etc
  //                 OR'd together) which will be associated with this
  //                 FD initially.
  virtual void AddFD(int fd, int event_mask) const;

  ////////////////////////////////////////

  // Summary:
  //   Modifies a file-descriptor in the set of FDs that should be
  //   monitored with epoll.
  //   Note that this only deals with modifying data relating -directly-
  //   with the epoll call.
  // Args:
  //   fd - the file descriptor to-be-added to the monitoring set
  //   event_mask - the event mask (consisting of EPOLLIN, EPOLLOUT, etc
  //                 OR'd together) which will be associated with this
  //                 FD after this call.
  virtual void ModFD(int fd, int event_mask) const;

  ////////////////////////////////////////

  // Summary:
  //   Modified the event mask associated with an FD in the set of
  //   data needed by epoll.
  //   Events are removed before they are added, thus, if ~0 is put
  //   in 'remove_event', whatever is put in 'add_event' will be
  //   the new event mask.
  //   If the file-descriptor specified is not registered in the
  //   epoll_server, then nothing happens as a result of this call.
  // Args:
  //   fd - the file descriptor whose event mask is to be modified
  //   remove_event - the events which are to be removed from the current
  //                  event_mask
  //   add_event - the events which are to be added to the current event_mask
  //
  //
  virtual void ModifyFD(int fd, int remove_event, int add_event);

  ////////////////////////////////////////

  // Summary:
  //   Waits for events, and calls HandleEvents() for each
  //   fd, event pair discovered to possibly have an event.
  //   Note that a callback (B) may get a spurious event if
  //   another callback (A) has closed a file-descriptor N, and
  //   the callback (B) has a newly opened file-descriptor, which
  //   also happens to be N.
  virtual void WaitForEventsAndCallHandleEvents(int64_t timeout_in_us,
                                                struct epoll_event events[],
                                                int events_size);

  // Summary:
  //   An internal function for implementing the ready list. It adds a fd's
  //   CBAndEventMask to the ready list. If the fd is already on the ready
  //   list, it is a no-op.
  void AddToReadyList(CBAndEventMask* cb_and_mask);

  // Summary:
  //   An internal function for implementing the ready list. It remove a fd's
  //   CBAndEventMask from the ready list. If the fd is not on the ready list,
  //   it is a no-op.
  void RemoveFromReadyList(const CBAndEventMask& cb_and_mask);

  // Summary:
  // Calls any pending alarms that should go off and reregisters them if they
  // were recurring.
  virtual void CallAndReregisterAlarmEvents();

  // The file-descriptor created for epolling
  int epoll_fd_;

  // The mapping of file-descriptor to CBAndEventMasks
  FDToCBMap cb_map_;

  // Custom hash function to be used by hash_set.
  struct AlarmCBHash {
    size_t operator()(AlarmCB* const& p) const {
      return reinterpret_cast<size_t>(p);
    }
  };

  // TODO(sushantj): Having this hash_set is avoidable. We currently have it
  // only so that we can enforce stringent checks that a caller can not register
  // the same alarm twice. One option is to have an implementation in which
  // this hash_set is used only in the debug mode.
  using AlarmCBMap = std::unordered_set<AlarmCB*, AlarmCBHash>;
  AlarmCBMap all_alarms_;

  TimeToAlarmCBMap alarm_map_;

  // The amount of time in microseconds that we'll wait before returning
  // from the WaitForEventsAndExecuteCallbacks() function.
  // If this is positive, wait that many microseconds.
  // If this is negative, wait forever, or for the first event that occurs
  // If this is zero, never wait for an event.
  int64_t timeout_in_us_;

  // This is nonzero only after the invocation of epoll_wait_impl within
  // WaitForEventsAndCallHandleEvents and before the function
  // WaitForEventsAndExecuteCallbacks returns.  At all other times, this is
  // zero. This enables us to have relatively accurate time returned from the
  // ApproximateNowInUs() function. See that function for more details.
  int64_t recorded_now_in_us_;

  // This is used to implement CallAndReregisterAlarmEvents. This stores
  // all alarms that were reregistered because OnAlarm() returned a
  // value > 0 and the time at which they should be executed is less that
  // the current time.  By storing such alarms in this map we ensure
  // that while calling CallAndReregisterAlarmEvents we do not call
  // OnAlarm on any alarm in this set. This ensures that we do not
  // go in an infinite loop.
  AlarmCBMap alarms_reregistered_and_should_be_skipped_;

  LIST_HEAD(ReadyList, CBAndEventMask) ready_list_;
  LIST_HEAD(TmpList, CBAndEventMask) tmp_list_;
  int ready_list_size_;
  // TODO(alyssar): make this into something that scales up.
  static const int events_size_ = 256;
  struct epoll_event events_[256];

#ifdef EPOLL_SERVER_EVENT_TRACING
  struct EventRecorder {
   public:
    EventRecorder() : num_records_(0), record_threshold_(10000) {}

    ~EventRecorder() { Clear(); }

    // When a number of events equals the record threshold,
    // the collected data summary for all FDs will be written
    // to EPOLL_LOG(INFO). Note that this does not include the
    // individual events (if you'reinterested in those, you'll
    // have to get at them programmatically).
    // After any such flushing to EPOLL_LOG(INFO) all events will
    // be cleared.
    // Note that the definition of an 'event' is a bit 'hazy',
    // as it includes the 'Unregistration' event, and perhaps
    // others.
    void set_record_threshold(int64_t new_threshold) {
      record_threshold_ = new_threshold;
    }

    void Clear() {
      for (int i = 0; i < debug_events_.size(); ++i) {
        delete debug_events_[i];
      }
      debug_events_.clear();
      unregistered_fds_.clear();
      event_counts_.clear();
    }

    void MaybeRecordAndClear() {
      ++num_records_;
      if ((num_records_ > record_threshold_) && (record_threshold_ > 0)) {
        EPOLL_LOG(INFO) << "\n" << *this;
        num_records_ = 0;
        Clear();
      }
    }

    void RecordFDMaskEvent(int fd, int mask, const char* function) {
      FDMaskOutput* fdmo = new FDMaskOutput(fd, mask, function);
      debug_events_.push_back(fdmo);
      MaybeRecordAndClear();
    }

    void RecordEpollWaitEvent(int timeout_in_ms, int num_events_generated) {
      EpollWaitOutput* ewo =
          new EpollWaitOutput(timeout_in_ms, num_events_generated);
      debug_events_.push_back(ewo);
      MaybeRecordAndClear();
    }

    void RecordEpollEvent(int fd, int event_mask) {
      Events& events_for_fd = event_counts_[fd];
      events_for_fd.AssignFromMask(event_mask);
      MaybeRecordAndClear();
    }

    friend ostream& operator<<(ostream& os, const EventRecorder& er) {
      for (int i = 0; i < er.unregistered_fds_.size(); ++i) {
        os << "fd: " << er.unregistered_fds_[i] << "\n";
        os << er.unregistered_fds_[i];
      }
      for (EventCountsMap::const_iterator i = er.event_counts_.begin();
           i != er.event_counts_.end(); ++i) {
        os << "fd: " << i->first << "\n";
        os << i->second;
      }
      for (int i = 0; i < er.debug_events_.size(); ++i) {
        os << *(er.debug_events_[i]) << "\n";
      }
      return os;
    }

    void RecordUnregistration(int fd) {
      EventCountsMap::iterator i = event_counts_.find(fd);
      if (i != event_counts_.end()) {
        unregistered_fds_.push_back(i->second);
        event_counts_.erase(i);
      }
      MaybeRecordAndClear();
    }

   protected:
    class DebugOutput {
     public:
      friend ostream& operator<<(ostream& os, const DebugOutput& debug_output) {
        debug_output.OutputToStream(os);
        return os;
      }
      virtual void OutputToStream(ostream* os) const = 0;
      virtual ~DebugOutput() {}
    };

    class FDMaskOutput : public DebugOutput {
     public:
      FDMaskOutput(int fd, int mask, const char* function)
          : fd_(fd), mask_(mask), function_(function) {}
      virtual void OutputToStream(ostream* os) const {
        (*os) << "func: " << function_ << "\tfd: " << fd_;
        if (mask_ != 0) {
          (*os) << "\tmask: " << EventMaskToString(mask_);
        }
      }
      int fd_;
      int mask_;
      const char* function_;
    };

    class EpollWaitOutput : public DebugOutput {
     public:
      EpollWaitOutput(int timeout_in_ms, int num_events_generated)
          : timeout_in_ms_(timeout_in_ms),
            num_events_generated_(num_events_generated) {}
      virtual void OutputToStream(ostream* os) const {
        (*os) << "timeout_in_ms: " << timeout_in_ms_
              << "\tnum_events_generated: " << num_events_generated_;
      }

     protected:
      int timeout_in_ms_;
      int num_events_generated_;
    };

    struct Events {
      Events()
          : epoll_in(0),
            epoll_pri(0),
            epoll_out(0),
            epoll_rdnorm(0),
            epoll_rdband(0),
            epoll_wrnorm(0),
            epoll_wrband(0),
            epoll_msg(0),
            epoll_err(0),
            epoll_hup(0),
            epoll_oneshot(0),
            epoll_et(0) {}

      void AssignFromMask(int event_mask) {
        if (event_mask & EPOLLIN) ++epoll_in;
        if (event_mask & EPOLLPRI) ++epoll_pri;
        if (event_mask & EPOLLOUT) ++epoll_out;
        if (event_mask & EPOLLRDNORM) ++epoll_rdnorm;
        if (event_mask & EPOLLRDBAND) ++epoll_rdband;
        if (event_mask & EPOLLWRNORM) ++epoll_wrnorm;
        if (event_mask & EPOLLWRBAND) ++epoll_wrband;
        if (event_mask & EPOLLMSG) ++epoll_msg;
        if (event_mask & EPOLLERR) ++epoll_err;
        if (event_mask & EPOLLHUP) ++epoll_hup;
        if (event_mask & EPOLLONESHOT) ++epoll_oneshot;
        if (event_mask & EPOLLET) ++epoll_et;
      }

      friend ostream& operator<<(ostream& os, const Events& ev) {
        if (ev.epoll_in) {
          os << "\t      EPOLLIN: " << ev.epoll_in << "\n";
        }
        if (ev.epoll_pri) {
          os << "\t     EPOLLPRI: " << ev.epoll_pri << "\n";
        }
        if (ev.epoll_out) {
          os << "\t     EPOLLOUT: " << ev.epoll_out << "\n";
        }
        if (ev.epoll_rdnorm) {
          os << "\t  EPOLLRDNORM: " << ev.epoll_rdnorm << "\n";
        }
        if (ev.epoll_rdband) {
          os << "\t  EPOLLRDBAND: " << ev.epoll_rdband << "\n";
        }
        if (ev.epoll_wrnorm) {
          os << "\t  EPOLLWRNORM: " << ev.epoll_wrnorm << "\n";
        }
        if (ev.epoll_wrband) {
          os << "\t  EPOLLWRBAND: " << ev.epoll_wrband << "\n";
        }
        if (ev.epoll_msg) {
          os << "\t     EPOLLMSG: " << ev.epoll_msg << "\n";
        }
        if (ev.epoll_err) {
          os << "\t     EPOLLERR: " << ev.epoll_err << "\n";
        }
        if (ev.epoll_hup) {
          os << "\t     EPOLLHUP: " << ev.epoll_hup << "\n";
        }
        if (ev.epoll_oneshot) {
          os << "\t EPOLLONESHOT: " << ev.epoll_oneshot << "\n";
        }
        if (ev.epoll_et) {
          os << "\t      EPOLLET: " << ev.epoll_et << "\n";
        }
        return os;
      }

      unsigned int epoll_in;
      unsigned int epoll_pri;
      unsigned int epoll_out;
      unsigned int epoll_rdnorm;
      unsigned int epoll_rdband;
      unsigned int epoll_wrnorm;
      unsigned int epoll_wrband;
      unsigned int epoll_msg;
      unsigned int epoll_err;
      unsigned int epoll_hup;
      unsigned int epoll_oneshot;
      unsigned int epoll_et;
    };

    std::vector<DebugOutput*> debug_events_;
    std::vector<Events> unregistered_fds_;
    using EventCountsMap = std::unordered_map<int, Events>;
    EventCountsMap event_counts_;
    int64_t num_records_;
    int64_t record_threshold_;
  };

  void ClearEventRecords() { event_recorder_.Clear(); }
  void WriteEventRecords(ostream* os) const { (*os) << event_recorder_; }

  mutable EventRecorder event_recorder_;

#endif

 private:
  // Helper functions used in the destructor.
  void CleanupFDToCBMap();
  void CleanupTimeToAlarmCBMap();

  // The callback registered to the fds below.  As the purpose of their
  // registration is to wake the epoll server it just clears the pipe and
  // returns.
  std::unique_ptr<ReadPipeCallback> wake_cb_;

  // A pipe owned by the epoll server.  The server will be registered to listen
  // on read_fd_ and can be woken by Wake() which writes to write_fd_.
  int read_fd_;
  int write_fd_;

  // This boolean is checked to see if it is false at the top of the
  // WaitForEventsAndExecuteCallbacks function. If not, then it either returns
  // without doing work, and logs to ERROR, or aborts the program (in
  // DEBUG mode). If so, then it sets the bool to true, does work, and
  // sets it back to false when done. This catches unwanted recursion.
  bool in_wait_for_events_and_execute_callbacks_;

  // Returns true when the SimpleEpollServer() is being destroyed.
  bool in_shutdown_;
  int64_t last_delay_in_usec_;
};

class EpollAlarmCallbackInterface {
 public:
  // Summary:
  //   Called when an alarm times out. Invalidates an AlarmRegToken.
  //   WARNING: If a token was saved to refer to an alarm callback, OnAlarm must
  //   delete it, as the reference is no longer valid.
  // Returns:
  //   the unix time (in microseconds) at which this alarm should be signaled
  //   again, or 0 if the alarm should be removed.
  virtual int64_t OnAlarm() = 0;

  // Summary:
  //   Called when the an alarm is registered. Invalidates an AlarmRegToken.
  // Args:
  //   token: the iterator to the alarm registered in the alarm map.
  //   WARNING: this token becomes invalid when the alarm fires, is
  //   unregistered, or OnShutdown is called on that alarm.
  //   eps: the epoll server the alarm is registered with.
  virtual void OnRegistration(const SimpleEpollServer::AlarmRegToken& token,
                              SimpleEpollServer* eps) = 0;

  // Summary:
  //   Called when the an alarm is unregistered.
  //   WARNING: It is not valid to unregister a callback and then use the token
  //   that was saved to refer to the callback.
  virtual void OnUnregistration() = 0;

  // Summary:
  //   Called when the epoll server is shutting down.
  //   Invalidates the AlarmRegToken that was given when this alarm was
  //   registered.
  virtual void OnShutdown(SimpleEpollServer* eps) = 0;

  virtual ~EpollAlarmCallbackInterface() {}

 protected:
  EpollAlarmCallbackInterface() {}
};

// A simple alarm which unregisters itself on destruction.
//
// PLEASE NOTE:
// Any classes overriding these functions must either call the implementation
// of the parent class, or is must otherwise make sure that the 'registered_'
// boolean and the token, 'token_', are updated appropriately.
class EPOLL_EXPORT_PRIVATE 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_
