AG_EventLoop —
    agar low-level event loop
The AG_EventLoop routine loops,
    continually checking for low-level events and processing them. Its operation
    is governed by a registered set of
    Event
    Sinks which determine the type of low-level events to monitor, and
    the procedures to invoke in order to handle them.
The most common type of low-level events are:
  - Activity on a socket or file descriptor.
 
  - Expiration of a timer.
 
  - Kernel-event notifications (e.g.,
      kqueue(2)
      events). This includes filesystem events and process monitoring.
 
Concurrent instances of
    AG_EventLoop()
    are allowed in multithreaded builds. In threaded builds, event sinks are
    associated with running thread at the time of creation (in thread-local
    storage).
int
  
  AG_EventLoop(void);
  
  void
  
  AG_Terminate(int
    exitCode);
  
  void
  
  AG_TerminateEv(AG_Event
    *event);
AG_EventLoop()
    blocks the current thread, waiting for low-level events, and processing them
    until termination is requested. Its operation is governed by the registered
    set of event sinks.
The
    AG_Terminate()
    function requests termination of the event loop associated with the current
    thread. If the current thread is the main thread,
    AG_Terminate() will terminate the application with
    exitCode as return code. The
    AG_TerminateEv() variant accepts an
    AG_Event style argument instead of an
    int for the exit code.
AG_EventSink *
  
  AG_AddEventSink(enum
    ag_event_sink_type type,
    int ident,
    Uint flags,
    AG_EventSinkFn fn,
    const char *fnArgs);
  
  void
  
  AG_DelEventSink(AG_EventSink
    *sink);
  
  void
  
  AG_DelEventsSinkByIdent(enum
    ag_event_sink_type type,
    int ident,
    Uint flags);
  
  AG_EventSink *
  
  AG_AddEventPrologue(AG_EventSinkFn
    fn, const char
    *fnArgs, ...);
  
  AG_EventSink *
  
  AG_AddEventEpilogue(AG_EventSinkFn
    fn, const char
    *fnArgs, ...);
  
  AG_EventSink *
  
  AG_AddEventSpinner(AG_EventSinkFn
    fn, const char
    *fnArgs, ...);
  
  void
  
  AG_DelEventPrologue(AG_EventSink
    *sink);
  
  void
  
  AG_DelEventEpilogue(AG_EventSink
    *sink);
  
  void
  
  AG_DelEventSpinner(AG_EventSink
    *sink);
The
    AG_AddEventSink()
    routine creates a new event sink under the current thread, and returns a
    pointer to a newly-allocated AG_EventSink structure.
    The type argument may be one of:
  AG_SINK_READ 
  - Data is available for reading on file referenced by
      ident.
 
  AG_SINK_WRITE 
  - Data is available for writing on file referenced by
      ident.
 
  AG_SINK_FSEVENT 
  - A filesystem event has occurred on the file/directory referenced by
      ident. The type of event is specified in
      flags (see
      FILESYSTEM EVENTS for the
      accepted flags).
 
  AG_SINK_PROCEVENT 
  - An event has occurred on the monitored process
      ident. The type of event is specified in
      flags (see
      PROCESS EVENTS below).
 
The
    AG_DelEventSink()
    function destroys the specified event sink. The
    AG_DelEventSinksByIdent()
    function destroys all event sinks with matching ident
    and flags.
The
    AG_AddEventPrologue()
    function registers a callback routine to be invoked once at the start of
    AG_EventLoop().
    AG_AddEventEpilogue() registers a callback routine
    to be invoked on exit, before AG_EventLoop()
    returns. AG_DelEventEpilogue() and
    AG_DelEventPrologue() destroy the specified
    epilogue/prologue routine.
The
    AG_AddEventSpinner()
    routine registers a "spinner" callback routine. Spinner routines
    are invoked repeatedly and unconditionally by
    AG_EventLoop(), until the event loop terminates, or
    AG_DelEventSpinner() is invoked.
The
    AG_FileDlg(3)
    widget uses AG_SINK_FSEVENT to auto-refresh
    directory listings on platforms that offer filesystem monitoring
  capabilitie
The
    AG_ConsoleOpenFile(3)
    feature of
    AG_Console(3)
    sets up an event sink of type AG_SINK_READ to
    monitor changes on a file or stream.
The
    agardb(1)
    debugger uses AG_SINK_PROCEVENT to monitor events
    related to processes being debugged.
Agar's X11 driver
    AG_DriverGLX(3)
    sets up an event sink of type AG_SINK_READ in order
    to receive events from the X file descriptor:
Display *display;
static int
EventSink(AG_EventSink *es, AG_Event *event)
{
	Display *dpy = AG_PTR(1);
	while (XPending(dpy)) { /* Process event */ }
}
AG_AddEventSink(AG_SINK_READ,
    XConnectionNumber(display), 0,
    EventSink, "%p", display);
 
The AG_EventLoop call first appeared in
    Agar 1.0. Event sinks first appeared in Agar 1.5.0.