In computer science, the event loop, message dispatcher, message loop, message pump, or run loop is a programming construct that waits for and dispatches events or messages in a program.
It works by making a request to some internal or external "event provider" (that generally blocks the request until an event has arrived), and then it calls the relevant event handler ("dispatches the event").
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).
The event loop almost always operates asynchronously with the message originator.
A software library that provides asynchronous event notification.
The libevent
API provides a mechanism to execute a callback function when a specific event occurs on a file descriptor or after a timeout has been reached. libevent
also supports callbacks triggered by signals and regular timeouts.
Programs using libevent
:
- Chromium – Google's open-source web browser (uses Libevent on Mac and Linux)
- Memcached – a high-performance, distributed memory object caching system
- Transmission – a fast, easy, and free BitTorrent client
- NTP – the network time protocol that makes your clock right (uses Libevent in SNTP)
- tmux – A clean, modern, BSD-licensed terminal multiplexer, similar to GNU screen
- Tor – an anonymous Internet communication system.
- libevhtp – A fast and flexible replacement for libevent's httpd API
- Prosody – A Jabber/XMPP server written in Lua
- PgBouncer – Lightweight connection pooler for PostgreSQL
- redsocks – a simple transparent TCP -> Socks5/HTTPS proxy daemon.
- Vomit – Voice Over Misconfigured Internet Telephones
- Crawl – A Small and Efficient HTTP Crawler
- Libio – an input/output abstraction library
- Honeyd – a virtual honeynet daemon – can be used to fight Internet worms.
- Fragroute – an IDS testing tool
- Nylon – nested proxy server
- Disconcert – a Distributed Computing Framework for Loosely-Coupled Workstations.
- Trickle – a lightweight userspace bandwidth shaper.
- watchcatd –software watchdog designed to take actions not as drastic as the usual solutions, which reset the machine.
- ScanSSH – a fast SSH server and open proxy scanner.
- Nttlscan – a network topology scanner for Honeyd.
- NetChat – a combination of netcat and ppp's chat.
- Io – a small programming language; uses libevent for network communication.
- Systrace – a system call sandbox.
- SpyBye – detect malware on web pages.
- GreenSQL – an SQL database firewall.
- dnsscan – a fast scanner for identifying open recursive dns resolvers
- Kargo Event – a PHP extension for libevent.
- Scytale – a database encryption tool.
A full-featured and high-performance event loop that is loosely modelled after libevent
, but without its limitations and bugs.
It supports eight event types:
- I/O
- real time timers
- wall clock timers
- signals
- child status changes
- idle
- check
- prepare handlers
It uses a priority queue to manage timers and uses arrays as fundamental data structure. It has no artificial limitations on the number of watchers waiting for the same event. It offers an emulation layer for libevent and optionally the same DNS, HTTP and buffer management (by reusing the corresponding libevent code through its emulation layer).
It is used in:
- GNU Virtual Private Ethernet
- rxvt-unicode
- auditd
- the Deliantra MORPG Server and Client
- many other programs
// a single header file is required
#include <ev.h>
#include <stdio.h> // for puts
// every watcher type has its own typedef'd struct
// with the name ev_TYPE
ev_io stdin_watcher;
ev_timer timeout_watcher;
// all watcher callbacks have a similar signature
// this callback is called when data is readable on stdin
static void
stdin_cb (EV_P_ ev_io *w, int revents)
{
puts ("stdin ready");
// for one-shot events, one must manually stop the watcher
// with its corresponding stop function.
ev_io_stop (EV_A_ w);
// this causes all nested ev_run's to stop iterating
ev_break (EV_A_ EVBREAK_ALL);
}
// another callback, this time for a time-out
static void
timeout_cb (EV_P_ ev_timer *w, int revents)
{
puts ("timeout");
// this causes the innermost ev_run to stop iterating
ev_break (EV_A_ EVBREAK_ONE);
}
int
main (void)
{
// use the default event loop unless you have special needs
struct ev_loop *loop = EV_DEFAULT;
// initialise an io watcher, then start it
// this one will watch for stdin to become readable
ev_io_init (&stdin_watcher, stdin_cb, /*STDIN_FILENO*/ 0, EV_READ);
ev_io_start (loop, &stdin_watcher);
// initialise a timer watcher, then start it
// simple non-repeating 5.5 second timeout
ev_timer_init (&timeout_watcher, timeout_cb, 5.5, 0.);
ev_timer_start (loop, &timeout_watcher);
// now wait for events to arrive
ev_run (loop, 0);
// break was called, so exit
return 0;
}
A multi-platform support library with a focus on asynchronous I/O.
It was primarily developed for use by Node.js, but it's also used by Mozilla's Rust language, Luvit, Julia, pyuv, and others.
Features:
- Full-featured event loop backed by epoll, kqueue, IOCP, event ports.
- Asynchronous TCP and UDP sockets
- Asynchronous DNS resolution
- Asynchronous file and file system operations
- File system events
- ANSI escape code controlled TTY
- IPC with socket sharing, using Unix domain sockets or named pipes (Windows)
- Child processes
- Thread pool
- Signal handling
- High resolution clock
- Threading and synchronization primitives
libuv
(https://github.com/joyent/libuv) is a lightweight library which allows asynchronous IO across OpenBSD, Linux, Darwin, Windows etc by utilizing the fastest implementation on each system (epoll
, kqueue
, IOCP, event ports). These specialized IO polling methods are much faster on their respective platforms than just using select()
like the RTS currently does.
Additionally, it also provides cross platform threads, mutex, condition vars, terminal input/output and term settings w/ cross platform ANSI escape code handling, thread pools, cross platform HRC's etc. It's currently significantly faster than libevent
and slightly faster than libev
. Because it's maintained and utilized heavily by Node.js it's in extremely active and maintained development.
The GLib event loop manages all the sources of an event available for GLib. These events can come from different kinds of sources like file descriptors (plain file descriptors, sockets, or pipes), time-outs, or any kind of source that can be added.
Example:
#include <glib.h>
gboolean timeout_callback(gpointer data)
{
static int i = 0;
i++;
g_print("timeout_callback called %d times\n", i);
if (10 == i)
{
g_main_loop_quit( (GMainLoop*)data );
return FALSE;
}
return TRUE;
}
int main()
{
GMainLoop *loop;
loop = g_main_loop_new ( NULL , FALSE );
// add source to default context
g_timeout_add (100 , timeout_callback , loop);
g_main_loop_run (loop);
g_main_loop_unref(loop);
return 0;
}
http://devlib.symbian.slions.net/s3/GUID-7FD05006-09C1-4EF4-A2EB-AD98C2FA8866.html
https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html
Boost.Asio is a cross-platform C++ library for network and low-level I/O programming that provides developers with a consistent asynchronous model using a modern C++ approach.
http://www.boost.org/doc/libs/1_51_0/doc/html/boost_asio.html
As for design philosophy, libev
was created to improve on some of the architectural decisions in libevent
, for example, global variable usage made it hard to use libevent
safely in multithreaded environments, watcher structures are big because they combine I/O, time and signal handlers in one, the extra components such as the http and dns servers suffered from bad implementation quality and resultant security issues, and timers were inexact and didn't cope well with time jumps.
Libev
tried to improve each of these, by not using global variables but using a loop context for all functions, by using small watchers for each event type (an I/O watcher uses 56 bytes on x86_64 compared to 136 for libevent
), allowing extra event types such as timers based on wallclock vs. monotonic time, inter-thread interruptions, prepare and check watchers to embed other event loops or to be embedded and so on.
The extra component problem is "solved" by not having them at all, so libev
can be small and efficient, but you also need to look elsewhere for an http library, because libev simply doesn't have one (for example, there is a very related library called libeio that does asynchronous I/O, which can be used independently or together with libev
, so you can mix and match).
So in short, libev
tries to do one thing only (POSIX event library), and this in the most efficient way possible. Libevent
tries to give you the full solution (event lib, non-blocking I/O library, http server, DNS client).
Or, even shorter, libev
tries to follow the UNIX toolbox philosophy of doing one thing only, as good as possible.
http://stackoverflow.com/questions/9433864/whats-the-difference-between-libev-and-libevent/13999821
libuv Boost
Event Loop: yes Asio
Thread Pool: yes Asio + Threads
Threading:
Threads: yes Threads
Synchronization: yes Threads
File System Operations:
Synchronous: yes FileSystem
Asynchronous: yes Asio + Filesystem
Timers: yes Asio
Scatter/Gather I/O: no Asio
Networking:
ICMP: no Asio
DNS Resolution: async-only Asio
SSL: no Asio
TCP: async-only Asio
UDP: async-only Asio
Signal:
Handling: yes Asio
Sending: yes no
IPC:
UNIX Domain Sockets: yes Asio
Windows Named Pipe: yes Asio
Process Management:
Detaching: yes Process
I/O Pipe: yes Process
Spawning: yes Process
System Queries:
CPU: yes no
Network Interface: yes no
Serial Ports: no yes
TTY: yes no
Shared Library Loading: yes Extension
More details: http://stackoverflow.com/questions/11423426/how-does-libuv-compare-to-boost-asio/13220533
- https://en.wikipedia.org/wiki/Event_loop
- http://libevent.org
- http://www.wangafu.net/~nickm/libevent-book/
- http://libuv.org
- http://docs.libuv.org/en/v1.x/
- http://software.schmorp.de/pkg/libev.html
- http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod
- http://stackoverflow.com/questions/11423426/how-does-libuv-compare-to-boost-asio/13220533