16 Commits
Author SHA1 Message Date
Joachim Nilsson a8d8705c34 Bump version for v1.2.3 release.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2015-09-17 11:13:12 +02:00
Joachim Nilsson 4c03342c77 ChangeLog: Fix minor Markdown syntax error.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2015-09-17 11:11:33 +02:00
Joachim Nilsson c1fe3be3e7 README: Further simplifications.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2015-09-17 11:09:41 +02:00
Joachim Nilsson 861bf14d71 Update ChangeLog for v1.2.3 release.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2015-09-17 10:58:15 +02:00
Joachim Nilsson 395d2df573 README: Add more sub-sections to API chapter, readability.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2015-09-17 10:21:11 +02:00
Joachim Nilsson 2132ab1bd5 Let make test also run the test, like in the automake world.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2015-09-16 22:55:15 +02:00
Joachim Nilsson d62ae8f041 Rename CHANGELOG.md --> ChangeLog.md
- Rename to more common ChangeLog
- Drop TODO from distribution, only for devs

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2015-09-16 18:07:40 +02:00
Joachim Nilsson 1b1397b4ee Bump version to 1.2.3-beta1, prepare for upcoming v1.2.3 release.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2015-09-16 18:06:10 +02:00
Joachim Nilsson 7bf5c8d8d7 Let Travis run some tests as well.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2015-09-16 18:05:31 +02:00
Joachim Nilsson 1374661d4b README: Fix syntax error in example.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2015-09-16 18:05:04 +02:00
Joachim Nilsson 694e2b5ab9 Silence annoying warnings from GNU ar
In (very) modern versions of binutils, for instance v2.25.1 in Ubuntu
15.10, complain about VERY common `crus` argument.  This patch attempts
to silence this noise:

    $ make -j5
      CC      uev.o
      CC      io.o
      CC      timer.o
      CC      signal.o
      ARCHIVE libuev.a
      LINK    libuev.so.1
    ar: `u' modifier ignored since `D' is the default (see `U')

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2015-09-16 18:04:06 +02:00
Joachim Nilsson c2751af452 README: Further fixes to missing Markdown links.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2015-09-13 01:10:02 +02:00
Joachim Nilsson 1ce9fde395 README: Fix Markdown for code blocks.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2015-09-13 00:51:49 +02:00
Joachim Nilsson 7e9f8c4913 README: Fix Travis-CI and Coverity Markdown links.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2015-09-13 00:49:31 +02:00
Joachim Nilsson dd09c7c3a9 README: More Markdown syntax fixes.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2015-09-13 00:47:49 +02:00
Joachim Nilsson fe04723353 README: Markdown syntax (non-GitHub) fixes.
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2015-09-13 00:46:20 +02:00
6 changed files with 160 additions and 100 deletions

No files matched your search

+5 -1
View File
@@ -20,4 +20,8 @@ addons:
build_command: "make" build_command: "make"
branch_pattern: dev branch_pattern: dev
script: make # We don't use configure, so we must define our own build script.
script:
- make distclean
- make -j5
- make test
-1
View File
@@ -1 +0,0 @@
CHANGELOG.md
Symlink
+1
View File
@@ -0,0 +1 @@
ChangeLog.md
+33 -14
View File
@@ -3,6 +3,22 @@ Change Log
All notable changes to the project are documented in this file. All notable changes to the project are documented in this file.
[v1.2.3] - 2015-09-17
---------------------
Very minor release.
### Changes
- [README.md][] updates, mostly cleanup and readability improvements
- `make test` now runs the test case, on behalf of Travis-CI
- Renamed CHANGELOG.md to [ChangeLog.md][]
- Dropped [TODO.md][] from distribution archives, only for devs
### Fixes
- Lots of Markdown syntax fixes in both README and ChangeLog
- Silence annoying warning from newer GNU ar in Ubuntu 15.10
[v1.2.2] - 2015-08-30 [v1.2.2] - 2015-08-30
--------------------- ---------------------
@@ -64,7 +80,7 @@ Massively improved error handling.
all watchers when an error count reaches a MAX value -- handles stale all watchers when an error count reaches a MAX value -- handles stale
descriptors or cases when kernel does not notice updated descriptors. descriptors or cases when kernel does not notice updated descriptors.
- Return error when stopping a watcher fails. - Return error when stopping a watcher fails.
- Update [README.md] with new `uev_*_start()` functions. - Update [README.md][] with new `uev_*_start()` functions.
- Bump dev version to 1.1 due to the number of significant changes. - Bump dev version to 1.1 due to the number of significant changes.
### Fixes ### Fixes
@@ -84,9 +100,9 @@ Massively improved error handling.
- Renamed `main.c` to `uev.c` - Renamed `main.c` to `uev.c`
- Move examples to `examples/` subdirectory - Move examples to `examples/` subdirectory
- Simplify automatic dependency calculation - Simplify automatic dependency calculation
- Add [TODO.md] for wishlist items - Add [TODO.md][] for wishlist items
- Add [CHANGELOG.md], attempt to align with http://keepachangelog.com - Add [CHANGELOG.md][ChangeLog.md], to align with http://keepachangelog.com
- Further updates to [README.md] - Further updates to [README.md][]
[v1.0.4] - 2015-01-24 [v1.0.4] - 2015-01-24
@@ -98,7 +114,7 @@ Release mainly targeted for [Finit development](https://github.com/troglobit/fin
### Changes ### Changes
* `test.c` has been simplified/clarified * `test.c` has been simplified/clarified
* Further updates to [README.md] * Further updates to [README.md][]
* Minor update to Makefile, change how build progress is echoed * Minor update to Makefile, change how build progress is echoed
@@ -108,7 +124,7 @@ Release mainly targeted for [Finit development](https://github.com/troglobit/fin
This is a very minor release, with a strong focus on documentation. This is a very minor release, with a strong focus on documentation.
### Changes ### Changes
- [README.md], massively updated - [README.md][], massively updated
- API documentation, updated - API documentation, updated
- Travis CI integration added, https://travis-ci.org/troglobit/libuev - Travis CI integration added, https://travis-ci.org/troglobit/libuev
- Coverity Scan integration, https://scan.coverity.com/projects/3846 - Coverity Scan integration, https://scan.coverity.com/projects/3846
@@ -126,8 +142,8 @@ This is a very minor release, with a strong focus on documentation.
--------------------- ---------------------
### Changes ### Changes
- Cleanup and rewrite of [README.md] after first audit by @vonj - Cleanup and rewrite of [README.md][] after first audit by @vonj
- Added API and example section to [README.md] - Added API and example section to [README.md][]
- New [joystick.c] example added - New [joystick.c] example added
- `main.c:uev_run()`: Document mysterious flags parameter - `main.c:uev_run()`: Document mysterious flags parameter
@@ -146,17 +162,20 @@ First release in the new guise and API.
- Reindent to use Linux KNF - Reindent to use Linux KNF
- Change library name to libuev - Change library name to libuev
- Lua support removed - Lua support removed
- Make sure to state the [MIT license] correctly in all files - Make sure to state the [MIT license][] correctly in all files
- Import [Niels Provos]' `bench.c`, the [libev version] - Import [Niels Provos][]' `bench.c`, the [libev version][]
v0.0.1 - 2012-03-17 v0.0.1 - 2012-03-17
------------------- -------------------
[Initial announcement] of [libuevent] by [Flemming Madsen] to the Lua [Initial announcement][] of [libuevent][] by [Flemming Madsen][] to the
users mailing list. Lua users mailing list.
[UNRELEASED]: https://github.com/troglobit/libuev/compare/v1.2.1...HEAD
[UNRELEASED]: https://github.com/troglobit/libuev/compare/v1.2.3...HEAD
[v1.2.3]: https://github.com/troglobit/libuev/compare/v1.2.2...v1.2.3
[v1.2.2]: https://github.com/troglobit/libuev/compare/v1.2.1...v1.2.2
[v1.2.1]: https://github.com/troglobit/libuev/compare/v1.2.0...v1.2.1 [v1.2.1]: https://github.com/troglobit/libuev/compare/v1.2.0...v1.2.1
[v1.2.0]: https://github.com/troglobit/libuev/compare/v1.1.0...v1.2.0 [v1.2.0]: https://github.com/troglobit/libuev/compare/v1.1.0...v1.2.0
[v1.1.0]: https://github.com/troglobit/libuev/compare/v1.0.5...v1.1.0 [v1.1.0]: https://github.com/troglobit/libuev/compare/v1.0.5...v1.1.0
@@ -168,7 +187,7 @@ users mailing list.
[v1.0.0]: https://github.com/troglobit/libuev/compare/v0.0.1...v1.0.0 [v1.0.0]: https://github.com/troglobit/libuev/compare/v0.0.1...v1.0.0
[TODO.md]: https://github.com/troglobit/libuev/blob/master/TODO.md [TODO.md]: https://github.com/troglobit/libuev/blob/master/TODO.md
[README.md]: https://github.com/troglobit/libuev/blob/master/README.md [README.md]: https://github.com/troglobit/libuev/blob/master/README.md
[CHANGLOG.md]: https://github.com/troglobit/libuev/blob/master/CHANGELOG.md [ChangeLog.md]: https://github.com/troglobit/libuev/blob/master/ChangeLog.md
[joystick.c]: https://github.com/troglobit/libuev/blob/master/joystick.c [joystick.c]: https://github.com/troglobit/libuev/blob/master/joystick.c
[Niels Provos]: http://en.wikipedia.org/wiki/Niels_Provos [Niels Provos]: http://en.wikipedia.org/wiki/Niels_Provos
[MIT license]: http://en.wikipedia.org/wiki/MIT_License [MIT license]: http://en.wikipedia.org/wiki/MIT_License
+5 -4
View File
@@ -27,7 +27,7 @@
ROOTDIR ?= $(shell pwd) ROOTDIR ?= $(shell pwd)
#VERSION = $(shell git tag -l | tail -1) #VERSION = $(shell git tag -l | tail -1)
VERSION ?= 1.2.2 VERSION ?= 1.2.3
NAME = libuev NAME = libuev
PKG = $(NAME)-$(VERSION) PKG = $(NAME)-$(VERSION)
ARCHIVE = $(PKG).tar.xz ARCHIVE = $(PKG).tar.xz
@@ -45,7 +45,7 @@ CPPFLAGS += -W -Wall -Werror
ARFLAGS = crus ARFLAGS = crus
MAKEFLAGS = --no-print-directory --silent MAKEFLAGS = --no-print-directory --silent
DISTFILES = README CHANGELOG TODO LICENSE DISTFILES = README ChangeLog LICENSE
HEADERS = uev.h private.h queue.h HEADERS = uev.h private.h queue.h
OBJS := uev.o io.o timer.o signal.o OBJS := uev.o io.o timer.o signal.o
SRCS := $(OBJS:.o=.c) SRCS := $(OBJS:.o=.c)
@@ -82,7 +82,7 @@ $(SOLIB): Makefile $(OBJS)
$(STATICLIB): Makefile $(OBJS) $(STATICLIB): Makefile $(OBJS)
@printf " ARCHIVE $@\n" @printf " ARCHIVE $@\n"
@$(AR) $(ARFLAGS) $@ $(OBJS) @$(AR) $(ARFLAGS) $@ $(OBJS) 2>/dev/null
install-exec: all install-exec: all
@printf " INSTALL $(DESTDIR)$(libdir)/$(SOLIB)\n" @printf " INSTALL $(DESTDIR)$(libdir)/$(SOLIB)\n"
@@ -126,8 +126,9 @@ bench: Makefile $(STATICLIB)
examples: all examples: all
@$(MAKE) -C examples @$(MAKE) -C examples
test joystick: test joystick: all
@$(MAKE) -C examples $@ @$(MAKE) -C examples $@
@./examples/$@
# Runs Clang scan-build on the whole tree # Runs Clang scan-build on the whole tree
check: clean check: clean
+116 -80
View File
@@ -1,6 +1,6 @@
libuEv | Simple event loop for Linux libuEv | Simple event loop for Linux
==================================== ====================================
[![Travis Status]][Travis] [![Coverity Status]][Coverity Scan] [![Travis Status][]][Travis] [![Coverity Status][]][Coverity Scan]
Table of Contents Table of Contents
@@ -8,7 +8,11 @@ Table of Contents
* [Introduction](#introduction) * [Introduction](#introduction)
* [API](#api) * [API](#api)
* [Example](#example) * [Create an Event Context](#create-an-event-context)
* [Register an Event Watcher](#register-an-event-watcher)
* [Start Event Loop](#start-event-loop)
* [Summary](#summary)
* [Joystick Example](#joystick-example)
* [Build & Install](#build--install) * [Build & Install](#build--install)
* [Origin & References](#origin--references) * [Origin & References](#origin--references)
@@ -44,13 +48,13 @@ core, even though they run Linux, with multiple threads a program may
actually run slower! Always profile your program, and if possible, test actually run slower! Always profile your program, and if possible, test
it on different architectures. it on different architectures.
[libuEv] is a simple event loop in the style of the more established [libuEv][] is a simple event loop in the style of the more established
[libevent][1], [libev][2] and the venerable [Xt(3)][3] event loop. The [libevent][1], [libev][2] and the venerable [Xt(3)][3] event loop. The
*u* (micro) in the name refers to both the small feature set and the *u* (micro) in the name refers to both the small feature set and the
small size overhead impact of the library. The primary target of small size overhead impact of the library. The primary target of
[libuEv] is a modern Linux system. [libuEv][] is a modern Linux system.
Experienced developers may appreciate that [libuEv] is built on top of Experienced developers may appreciate that [libuEv][] is built on top of
modern Linux APIs: epoll, timerfd and signalfd. Note, a certain amount modern Linux APIs: epoll, timerfd and signalfd. Note, a certain amount
of care is needed when dealing with APIs that employ signalfd. For of care is needed when dealing with APIs that employ signalfd. For
details, see [this article][4] at [lwn.net](http://lwn.net). details, see [this article][4] at [lwn.net](http://lwn.net).
@@ -61,18 +65,19 @@ details, see [this article][4] at [lwn.net](http://lwn.net).
API API
--- ---
The C interface to [libuEv] is very simple. It handles three different The C interface to [libuEv][] is very simple. It handles three different
types of events: I/O (files, sockets, message queues, etc.), timers, and types of events: I/O (files, sockets, message queues, etc.), timers, and
signals. With a slight caveat on signals signals. With a slight caveat on signals
```C ```C
/* Callback example, arg is passed from watcher's *_init() /* Callback example, arg is passed from watcher's *_init()
* w->fd holds the file descriptor, events is set by libuEv * w->fd holds the file descriptor, events is set by libuEv
* to indicate if any of UEV_READ and/or UEV_WRITE is ready. * to indicate if any of UEV_READ and/or UEV_WRITE is ready.
*/ */
void callback (uev_t *w, void *arg, int events); void callback (uev_t *w, void *arg, int events);
/* Event loop functions, notice use of flags! */ /* Event loop: Notice the use of flags! */
int uev_init (uev_ctx_t *ctx); int uev_init (uev_ctx_t *ctx);
int uev_exit (uev_ctx_t *ctx); int uev_exit (uev_ctx_t *ctx);
int uev_run (uev_ctx_t *ctx, int flags); /* UEV_NONE, UEV_ONCE, and/or UEV_NONBLOCK */ int uev_run (uev_ctx_t *ctx, int flags); /* UEV_NONE, UEV_ONCE, and/or UEV_NONBLOCK */
@@ -94,57 +99,84 @@ signals. With a slight caveat on signals
int uev_signal_set (uev_t *w, int signo); /* Change signal to wait for */ int uev_signal_set (uev_t *w, int signo); /* Change signal to wait for */
int uev_signal_start(uev_t *w); /* Restart a stopped signal watcher */ int uev_signal_start(uev_t *w); /* Restart a stopped signal watcher */
int uev_signal_stop (uev_t *w); /* Stop signal watcher */ int uev_signal_stop (uev_t *w); /* Stop signal watcher */
``` ```
### Create an Event Context
To monitor events the developer first creates an *event context*, this To monitor events the developer first creates an *event context*, this
is achieved by calling `uev_init()` with a pointer to a (thread) local is achieved by calling `uev_init()` with a pointer to a (thread) local
`uev_ctx_t` variable. `uev_ctx_t` variable.
```C ```C
uev_ctx_t ctx; uev_ctx_t ctx;
uev_init(&ctx); uev_init(&ctx);
``` ```
Then, for each event to be monitored, a *watcher* is registered with the ### Register an Event Watcher
event context. The watcher, an `uev_t`, is initialized with the proper
file descriptor to monitor, and an event callback function, by calling For each event to be monitored, be it a signal, timer or a file
the event type's `_init()` function with the `uev_ctx_t` context. descriptor, a *watcher* must be registered with the event context. The
watcher, an `uev_t`, is registered by calling the event type's `_init()`
function with the `uev_ctx_t` context, the callback, and an optional
argument.
Here is a signal example:
```C ```C
void cleanup_exit(uev_t *w, void *arg, int events) void cleanup_exit(uev_t *w, void *arg, int events)
{ {
/* Graceful exit, with optional cleanup ... */ /* Graceful exit, with optional cleanup ... */
uev_exit(w->ctx); uev_exit(w->ctx);
} }
uev_t termw; int main(void)
{
uev_t sigterm_watcher;
.
.
.
uev_signal_init(&ctx, &sigterm_watcher, cleanup_exit, NULL, SIGTERM);
.
.
.
}
uev_signal_init(&ctx, &term, cleanup_exit, NULL, SIGTERM);
``` ```
### Start Event Loop
When all watchers are registered, call the *event loop* with `uev_run()` When all watchers are registered, call the *event loop* with `uev_run()`
and the argument to the event context. The `flags` parameter can be and the argument to the event context. The `flags` parameter can be
used to integrate [libuEv] into another event loop. With `flags` set to used to integrate [libuEv][] into another event loop.
`UEV_ONCE` the event loop returns after having served the first event.
If `flags` is set to `UEV_ONCE | UEV_NONBLOCK` the event loop returns In this example we set `flags` to none:
immediately if no event is available.
```C ```C
uev_run(&ctx, UEV_NONE); uev_run(&ctx, UEV_NONE);
``` ```
In case of errors, stream close, or peer shutdown, libuEv handles much With `flags` set to `UEV_ONCE` the event loop returns as soon as it has
internally, but also lets the callback run. This is useful for stateful served the first event. If `flags` is set to `UEV_ONCE | UEV_NONBLOCK`
connections to be able to detect EOF. the event loop returns immediately if no event is available.
Summary: **Note:** libuEv handles many types of errors, stream close, or peer
shutdowns internally, but also lets the callback run. This is useful
for stateful connections to be able to detect EOF.
1. Prepare an event context with `uev_init()` ### Summary
2. Register event callbacks with `uev_io_init()`, `uev_signal_init()`
or `uev_timer_init()` 1. Set up an event context with `uev_init()`
3. Enter the event loop with `uev_run()` 2. Register event callbacks with the event context using
4. Leave the event loop with `uev_exit()`, possibly from a callback `uev_io_init()`, `uev_signal_init()` or `uev_timer_init()`
3. Start the event loop with `uev_run()`
4. Exit the event loop with `uev_exit()`, possibly from a callback
**Note 1:** Make sure to use non-blocking stream I/O! Most hard to find **Note 1:** Make sure to use non-blocking stream I/O! Most hard to find
bugs in event driven applications are due to sockets and files being bugs in event driven applications are due to sockets and files being
@@ -164,61 +196,63 @@ of this, from [finit][6], implementing `run()` as a better replacement
to `system()`, which sucks anyawy :) to `system()`, which sucks anyawy :)
Example Joystick Example
------- ----------------
Here follows a very brief example to illustrate how one can use [libuEv] Here follows a very brief example to illustrate how one can use
to act upon joystick input. [libuEv][] to act upon joystick input.
```C ```C
#include <err.h>
#include <errno.h>
#include <stdio.h>
#include <stdint.h>
#include <fcntl.h>
#include <unistd.h>
#include "uev.h" #include <err.h>
#include <errno.h>
#include <stdio.h>
#include <stdint.h>
#include <fcntl.h>
#include <unistd.h>
struct js_event { #include "uev.h"
uint32_t time; /* event timestamp in milliseconds */
int16_t value; /* value */
uint8_t type; /* event type */
uint8_t number; /* axis/button number */
} e;
static void joystick_cb(uev_t *w, void *arg, int events) struct js_event {
{ uint32_t time; /* event timestamp in milliseconds */
read (w->fd, &e, sizeof(e)); int16_t value; /* value */
uint8_t type; /* event type */
uint8_t number; /* axis/button number */
} e;
switch (e.type) { static void joystick_cb(uev_t *w, void *arg, int events)
case 1: {
if (e.value) printf("Button %d pressed\n", e.number); read (w->fd, &e, sizeof(e));
else printf("Button %d released\n", e.number);
break;
case 2: switch (e.type) {
printf("Joystick axis %d moved, value %d!\n", e.number, e.value); case 1:
break; if (e.value) printf("Button %d pressed\n", e.number);
} else printf("Button %d released\n", e.number);
} break;
int main(void) case 2:
{ printf("Joystick axis %d moved, value %d!\n", e.number, e.value);
int fd = open("/dev/input/js1", O_RDONLY, O_NONBLOCK); break;
uev_t js1_watcher; }
uev_ctx_t ctx; }
if (fd < 0) int main(void)
errx(errno, "Cannot find a joystick attached."); {
int fd = open("/dev/input/js1", O_RDONLY, O_NONBLOCK);
uev_t js1_watcher;
uev_ctx_t ctx;
uev_init(&ctx); if (fd < 0)
uev_io_init(&ctx, &js1_watcher, joystick_cb, NULL, fd, UEV_READ); errx(errno, "Cannot find a joystick attached.");
puts("Starting, press Ctrl-C to exit."); uev_init(&ctx);
uev_io_init(&ctx, &js1_watcher, joystick_cb, NULL, fd, UEV_READ);
puts("Starting, press Ctrl-C to exit.");
return uev_run(&ctx, 0);
}
return uev_run(&ctx, 0);
}
``` ```
To compile the program, save the code as `joystick.c` and call GCC with To compile the program, save the code as `joystick.c` and call GCC with
@@ -226,12 +260,13 @@ To compile the program, save the code as `joystick.c` and call GCC with
directory, skips using a Makefile altogether. Alternatively, call the directory, skips using a Makefile altogether. Alternatively, call the
`Makefile` with <kbd>make joystick</kbd> from this directory. `Makefile` with <kbd>make joystick</kbd> from this directory.
More complete and relevant example uses of [libuEv] is the TFTP/FTP More complete and relevant example uses of [libuEv][] is the TFTP/FTP
server [uftpd][5], and the Linux `/sbin/init` replacement [finit][6]. server [uftpd][5], and the Linux `/sbin/init` replacement [finit][6].
Both use [libuEv] as a GIT submodule. Both use [libuEv][] as a GIT submodule.
Also, see the `bench.c` program (<kbd>make bench</kbd> from within the Also see the `bench.c` program (<kbd>make bench</kbd> from within the
library) for [reference benchmarks][7] against libevent and libev. library) for [reference benchmarks][7] against [libevent][1] and
[libev][2].
Build & Install Build & Install
@@ -246,7 +281,7 @@ patches to support *BSD and its kqueue interface.
* <kbd>make test</kbd>: Test and showcase * <kbd>make test</kbd>: Test and showcase
* <kbd>make install</kbd>: Honors `$prefix` and `$DESTDIR` environment variables * <kbd>make install</kbd>: Honors `$prefix` and `$DESTDIR` environment variables
Size of [libuEv]: Size of [libuEv][]:
$ make strip $ make strip
CC main.o CC main.o
@@ -268,10 +303,13 @@ Size of [libuEv]:
Origin & References Origin & References
-------------------- --------------------
[libuEv] was originally based on [LibUEvent][8] by [Flemming Madsen] but [libuEv][] was originally based on [LibUEvent][8] by [Flemming Madsen]
has been completely rewritten with a much clearer API. Now more similar but has been completely rewritten with a much clearer API. Now more
to the famous [libev][2] by [Mark Lehmann]. Another small event library similar to the famous [libev][2] by [Mark Lehmann][]. Another small
used for inspiration is the very small [Picoev][9] by [Oku Kazuho]. event library used for inspiration is the very small [Picoev][9] by
[Oku Kazuho][].
[libuEv][] is developed and maintained by [Joachim Nilsson][].
[1]: http://libevent.org [1]: http://libevent.org
[2]: http://software.schmorp.de/pkg/libev.html [2]: http://software.schmorp.de/pkg/libev.html
@@ -286,15 +324,13 @@ used for inspiration is the very small [Picoev][9] by [Oku Kazuho].
[Travis Status]: https://travis-ci.org/troglobit/libuev.png?branch=master [Travis Status]: https://travis-ci.org/troglobit/libuev.png?branch=master
[Coverity Scan]: https://scan.coverity.com/projects/3846 [Coverity Scan]: https://scan.coverity.com/projects/3846
[Coverity Status]: https://scan.coverity.com/projects/3846/badge.svg [Coverity Status]: https://scan.coverity.com/projects/3846/badge.svg
[LibuEV]: https://github.com/troglobit/libuev [LibuEv]: https://github.com/troglobit/libuev
[Oku Kazuho]: https://github.com/kazuho [Oku Kazuho]: https://github.com/kazuho
[Mark Lehmann]: http://software.schmorp.de [Mark Lehmann]: http://software.schmorp.de
[Joachim Nilsson]: http://troglobit.com [Joachim Nilsson]: http://troglobit.com
[Flemming Madsen]: http://www.madsensoft.dk [Flemming Madsen]: http://www.madsensoft.dk
[Dave Zarzycki, Apple]: http://www.youtube.com/watch?v=cD_s6Fjdri8 [Dave Zarzycki, Apple]: http://www.youtube.com/watch?v=cD_s6Fjdri8
[libuEv] is developed and maintained by [Joachim Nilsson].
<!-- <!--
-- Local Variables: -- Local Variables:
-- mode: markdown -- mode: markdown