text: /* A simple event-driven programming library. Originally I wrote this code
   * for the Jim's event-loop (Jim is a Tcl interpreter) but later translated
   * it in form of a library for easy reuse.
   *
   * Copyright (c) 2006-2012, Salvatore Sanfilippo <antirez at gmail dot com>
   * All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions are met:
   *
   *   * Redistributions of source code must retain the above copyright notice,
   *     this list of conditions and the following disclaimer.
   *   * Redistributions in binary form must reproduce the above copyright
   *     notice, this list of conditions and the following disclaimer in the
   *     documentation and/or other materials provided with the distribution.
   *   * Neither the name of Redis nor the names of its contributors may be used
   *     to endorse or promote products derived from this software without
   *     specific prior written permission.
   *
   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   * POSSIBILITY OF SUCH DAMAGE.
   */
  
  #ifndef __AE_H__
  #define __AE_H__
  
  #define AE_OK 0
  #define AE_ERR -1
  
  #define AE_NONE 0
  #define AE_READABLE 1
  #define AE_WRITABLE 2
  
  #define AE_FILE_EVENTS 1
  #define AE_TIME_EVENTS 2
  #define AE_ALL_EVENTS (AE_FILE_EVENTS|AE_TIME_EVENTS)
  #define AE_DONT_WAIT 4
  
  #define AE_NOMORE -1
  
  /* Macros */
  #define AE_NOTUSED(V) ((void) V)
  
  struct aeEventLoop;
  
  /* Types and data structures */
  typedef void aeFileProc(struct aeEventLoop *eventLoop, int fd, void *clientData, int mask);
  typedef int aeTimeProc(struct aeEventLoop *eventLoop, long long id, void *clientData);
  typedef void aeEventFinalizerProc(struct aeEventLoop *eventLoop, void *clientData);
  typedef void aeBeforeSleepProc(struct aeEventLoop *eventLoop);
  
  /* File event structure */
  typedef struct aeFileEvent {
      int mask; /* one of AE_(READABLE|WRITABLE) */
      aeFileProc *rfileProc;
      aeFileProc *wfileProc;
      void *clientData;
  } aeFileEvent;
  
  /* Time event structure */
  typedef struct aeTimeEvent {
      long long id; /* time event identifier. */
      long when_sec; /* seconds */
      long when_ms; /* milliseconds */
      aeTimeProc *timeProc;
      aeEventFinalizerProc *finalizerProc;
      void *clientData;
      struct aeTimeEvent *next;
  } aeTimeEvent;
  
  /* A fired event */
  typedef struct aeFiredEvent {
      int fd;
      int mask;
  } aeFiredEvent;
  
  /* State of an event based program */
  typedef struct aeEventLoop {
      int maxfd;   /* highest file descriptor currently registered */
      int setsize; /* max number of file descriptors tracked */
      long long timeEventNextId;
      time_t lastTime;     /* Used to detect system clock skew */
      aeFileEvent *events; /* Registered events */
      aeFiredEvent *fired; /* Fired events */
      aeTimeEvent *timeEventHead;
      int stop;
      void *apidata; /* This is used for polling API specific data */
      aeBeforeSleepProc *beforesleep;
  } aeEventLoop;
  
  /* Prototypes */
  aeEventLoop *aeCreateEventLoop(int setsize);
  void aeDeleteEventLoop(aeEventLoop *eventLoop);
  void aeStop(aeEventLoop *eventLoop);
  int aeCreateFileEvent(aeEventLoop *eventLoop, int fd, int mask,
          aeFileProc *proc, void *clientData);
  void aeDeleteFileEvent(aeEventLoop *eventLoop, int fd, int mask);
  int aeGetFileEvents(aeEventLoop *eventLoop, int fd);
  long long aeCreateTimeEvent(aeEventLoop *eventLoop, long long milliseconds,
          aeTimeProc *proc, void *clientData,
          aeEventFinalizerProc *finalizerProc);
  int aeDeleteTimeEvent(aeEventLoop *eventLoop, long long id);
  int aeProcessEvents(aeEventLoop *eventLoop, int flags);
  int aeWait(int fd, int mask, long long milliseconds);
  void aeMain(aeEventLoop *eventLoop);
  char *aeGetApiName(void);
  void aeSetBeforeSleepProc(aeEventLoop *eventLoop, aeBeforeSleepProc *beforesleep);
  int aeGetSetSize(aeEventLoop *eventLoop);
  int aeResizeSetSize(aeEventLoop *eventLoop, int setsize);
  
  int aeApiCreate(aeEventLoop *eventLoop);
  int aeApiResize(aeEventLoop *eventLoop, int setsize);
  void aeApiFree(aeEventLoop *eventLoop);
  int aeApiAddEvent(aeEventLoop *eventLoop, int fd, int mask);
  void aeApiDelEvent(aeEventLoop *eventLoop, int fd, int delmask);
  int aeApiPoll(aeEventLoop *eventLoop, struct timeval *tvp);
  char *aeApiName(void);
  
  #endif
  