// 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_export.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 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_; }

  // 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_
