The event-loop may be used in conjunction with a reactor, if the event provider follows the file interface, which can be selected or 'polled' (the Unix system call, not actual polling).
This approach is in contrast to a number of other alternatives: Due to the predominance of graphical user interfaces, most modern applications feature a main loop.
The select and poll system calls allow a set of file descriptors to be monitored for a change of state, e.g. when data becomes available to be read.
For example, consider a program that reads from a continuously updated file and displays its contents in the X Window System, which communicates with clients over a socket (either Unix domain or Berkeley): One of the few things in Unix that does not conform to the file interface are asynchronous events (signals).
The solution arrived at by POSIX is the pselect() call, which is similar to select() but takes an additional sigmask parameter, which describes a signal mask.
[3] In Linux kernel version 2.6.22, a new system call signalfd() was added, which allows receiving signals via a special file descriptor.
An event can be user interaction, network traffic, system processing, timer activity, inter-process communication, among others.
GetMessage() blocks until a message, or "event", is received (with function PeekMessage() as a non-blocking alternative).
It is not safe to call Xlib functions from a signal handler, because the X application may have been interrupted in an arbitrary state, e.g. within XNextEvent.
Sources then communicate with observers through the run loop, with it organising queueing and dispatch of messages.
The CFRunLoop is abstracted in Cocoa as an NSRunLoop, which allows any message (equivalent to a function call in non-reflective runtimes) to be queued for dispatch to any object.