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