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.