mirror of
https://github.com/troglobit/libuev.git
synced 2026-10-23 11:24:34 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3e5694cb76 | ||
|
|
f5806a28c0 | ||
|
|
ef57250586 | ||
|
|
febace818b | ||
|
|
5496bf0931 | ||
|
|
cb93dd9c9d | ||
|
|
341f7801fd | ||
|
|
dd475b5058 | ||
|
|
0a1a0ebffb | ||
|
|
91bfe9faa7 | ||
|
|
ddfc1460eb | ||
|
|
71e6d78fdc | ||
|
|
5929295c37 | ||
|
|
412f04f413 | ||
|
|
f78348a92a | ||
|
|
d1f5062e79 | ||
|
|
1037eed481 | ||
|
|
2f9cce9150 | ||
|
|
f3b3177963 | ||
|
|
ad262efa97 | ||
|
|
0dfc9152bd | ||
|
|
9642443a7c | ||
|
|
98748277f3 | ||
|
|
1de445535e | ||
|
|
151f9294c9 | ||
|
|
61bb69795d | ||
|
|
d46ff8e396 | ||
|
|
e0cebc33b1 | ||
|
|
82a1018dd2 | ||
|
|
58ec8e1d6f | ||
|
|
704d7d5612 | ||
|
|
ce4f8d6ef5 | ||
|
|
6f5e6e5232 | ||
|
|
9751be5859 |
No files matched your search
+7
-1
@@ -7,8 +7,14 @@
|
|||||||
*.la
|
*.la
|
||||||
*.lo
|
*.lo
|
||||||
*.html
|
*.html
|
||||||
|
.config
|
||||||
.deps
|
.deps
|
||||||
.libs
|
.libs
|
||||||
|
.unpacked
|
||||||
|
ID
|
||||||
|
GTAGS
|
||||||
|
GRTAGS
|
||||||
|
GPATH
|
||||||
compile
|
compile
|
||||||
config.*
|
config.*
|
||||||
configure
|
configure
|
||||||
@@ -27,4 +33,4 @@ bench
|
|||||||
libuev*.tar.*
|
libuev*.tar.*
|
||||||
libuev.pc
|
libuev.pc
|
||||||
!libuev.pc.in
|
!libuev.pc.in
|
||||||
test-driver
|
test-driver
|
||||||
@@ -11,13 +11,21 @@ API Documentation
|
|||||||
* [Joystick Example](#joystick-example)
|
* [Joystick Example](#joystick-example)
|
||||||
|
|
||||||
|
|
||||||
|
> “Event driven software improves concurrency” -- [Dave Zarzycki, Apple][]
|
||||||
|
|
||||||
Introduction
|
Introduction
|
||||||
------------
|
------------
|
||||||
|
|
||||||
The C API to [libuEv][], listed in `uev/uev.h`, handles three different
|
The C API to [libuEv][], listed in `uev/uev.h`, handles three different
|
||||||
types of events: I/O (files, sockets, message queues, etc.), timers, and
|
types of events: I/O (pipes, sockets, message queues, etc.), timers, and
|
||||||
signals. The [Summary](#summary) details a slight caveat on signals.
|
signals. The [Summary](#summary) details a slight caveat on signals.
|
||||||
|
|
||||||
|
Notice the *lack of support for regular files* and directories. This is
|
||||||
|
a limitation of the underlying Linux `epoll` interface which will return
|
||||||
|
`EPERM` for regular files. Except for the special case when `stdin` is
|
||||||
|
redirected from the command line. See `examples/redirect.c` for more on
|
||||||
|
this particular case.
|
||||||
|
|
||||||
Timers can be either relative, timeout in milliseconds, or absolute with
|
Timers can be either relative, timeout in milliseconds, or absolute with
|
||||||
a time given in `time_t`, see `mktime()` et al. Absolute timers are
|
a time given in `time_t`, see `mktime()` et al. Absolute timers are
|
||||||
called cron timers and their callbacks get an `UEV_HUP` error event if
|
called cron timers and their callbacks get an `UEV_HUP` error event if
|
||||||
@@ -127,13 +135,24 @@ used to integrate [libuEv][] into another event loop.
|
|||||||
In this example we set `flags` to none:
|
In this example we set `flags` to none:
|
||||||
|
|
||||||
```C
|
```C
|
||||||
uev_run(&ctx, UEV_NONE);
|
result = uev_run(&ctx, UEV_NONE);
|
||||||
```
|
```
|
||||||
|
|
||||||
With `flags` set to `UEV_ONCE` the event loop returns as soon as it has
|
With `flags` set to `UEV_ONCE` the event loop returns as soon as it has
|
||||||
served the first event. If `flags` is set to `UEV_ONCE | UEV_NONBLOCK`
|
served the first event. If `flags` is set to `UEV_ONCE | UEV_NONBLOCK`
|
||||||
the event loop returns immediately if no event is available.
|
the event loop returns immediately if no event is available.
|
||||||
|
|
||||||
|
```
|
||||||
|
if (result < 0)
|
||||||
|
errx(result, "Unrecoverable event loop error, error %d", result);
|
||||||
|
```
|
||||||
|
|
||||||
|
If the call to `uev_run()` fails you should notify the user somehow.
|
||||||
|
libuEv fails if there is an invalid pointer, if `uev_init()` was not
|
||||||
|
called, or recurring `epoll()` errors thare are impossible to recover
|
||||||
|
from should occur. This is true for individual watchers as well, in
|
||||||
|
particular signal and timer watchers which can fail in miserable ways.
|
||||||
|
|
||||||
**Note:** libuEv handles many types of errors, stream close, or peer
|
**Note:** libuEv handles many types of errors, stream close, or peer
|
||||||
shutdowns internally, but also lets the callback run. This is useful
|
shutdowns internally, but also lets the callback run. This is useful
|
||||||
for stateful connections to be able to detect EOF.
|
for stateful connections to be able to detect EOF.
|
||||||
@@ -221,8 +240,20 @@ struct js_event {
|
|||||||
uint8_t number; /* axis/button number */
|
uint8_t number; /* axis/button number */
|
||||||
} e;
|
} e;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Called on any joystick event
|
||||||
|
*
|
||||||
|
* Note: We handle errors here by exiting, for a background daemon with
|
||||||
|
* multiple watchers you may want another approach.
|
||||||
|
*/
|
||||||
static void joystick_cb(uev_t *w, void *arg, int events)
|
static void joystick_cb(uev_t *w, void *arg, int events)
|
||||||
{
|
{
|
||||||
|
if (UEV_ERROR == events) {
|
||||||
|
/* Possibly joystick was unplugged */
|
||||||
|
warn("Unrecoverable error, exiting");
|
||||||
|
uev_exit(w->ctx);
|
||||||
|
}
|
||||||
|
|
||||||
read(w->fd, &e, sizeof(e));
|
read(w->fd, &e, sizeof(e));
|
||||||
|
|
||||||
switch (e.type) {
|
switch (e.type) {
|
||||||
@@ -281,3 +312,4 @@ library) for [reference benchmarks][7] against [libevent][1] and
|
|||||||
[7]: http://libev.schmorp.de/bench.html
|
[7]: http://libev.schmorp.de/bench.html
|
||||||
[LibuEv]: https://github.com/troglobit/libuev
|
[LibuEv]: https://github.com/troglobit/libuev
|
||||||
[GLIBC workaround]: https://sourceware.org/glibc/wiki/Y2038ProofnessDesign
|
[GLIBC workaround]: https://sourceware.org/glibc/wiki/Y2038ProofnessDesign
|
||||||
|
[Dave Zarzycki, Apple]: http://www.youtube.com/watch?v=cD_s6Fjdri8
|
||||||
+22
-7
@@ -4,6 +4,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.
|
||||||
|
|
||||||
|
|
||||||
|
[v2.0.0][] - 2017-11-11
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
Beware, this is a major release, introducing incompatible changes to the
|
||||||
|
failure modes of `uev_run()` and watcher callbacks. Most users will most
|
||||||
|
likely not notice any difference, but please read on.
|
||||||
|
|
||||||
|
### Changes
|
||||||
|
- `uev_run()` no longer exits the main event loop if an unrecoverable
|
||||||
|
error with a watcher occurs. Instead, the watcher is disabled and the
|
||||||
|
callback is run one last time with `events` set to `UEV_ERROR`.
|
||||||
|
- Watcher callbacks must handle `UEV_ERROR` conditions. This pertains
|
||||||
|
in particular to signal and timer watchers.
|
||||||
|
- Examples and API docs updated with the new failure modes.
|
||||||
|
|
||||||
|
|
||||||
[v1.6.0][] - 2017-09-18
|
[v1.6.0][] - 2017-09-18
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
@@ -280,7 +296,12 @@ v0.0.1 - 2012-03-17
|
|||||||
Lua users mailing list.
|
Lua users mailing list.
|
||||||
|
|
||||||
|
|
||||||
[UNRELEASED]: https://github.com/troglobit/libuev/compare/v1.4.2...HEAD
|
[UNRELEASED]: https://github.com/troglobit/libuev/compare/v2.0.0...HEAD
|
||||||
|
[v2.0.0]: https://github.com/troglobit/libuev/compare/v1.6.0...v2.0.0
|
||||||
|
[v1.6.0]: https://github.com/troglobit/libuev/compare/v1.5.2...v1.6.0
|
||||||
|
[v1.5.2]: https://github.com/troglobit/libuev/compare/v1.5.1...v1.5.2
|
||||||
|
[v1.5.1]: https://github.com/troglobit/libuev/compare/v1.5.0...v1.5.1
|
||||||
|
[v1.5.0]: https://github.com/troglobit/libuev/compare/v1.4.2...v1.5.0
|
||||||
[v1.4.2]: https://github.com/troglobit/libuev/compare/v1.4.1...v1.4.2
|
[v1.4.2]: https://github.com/troglobit/libuev/compare/v1.4.1...v1.4.2
|
||||||
[v1.4.1]: https://github.com/troglobit/libuev/compare/v1.4.0...v1.4.1
|
[v1.4.1]: https://github.com/troglobit/libuev/compare/v1.4.0...v1.4.1
|
||||||
[v1.4.0]: https://github.com/troglobit/libuev/compare/v1.3.1...v1.4.0
|
[v1.4.0]: https://github.com/troglobit/libuev/compare/v1.3.1...v1.4.0
|
||||||
@@ -307,9 +328,3 @@ Lua users mailing list.
|
|||||||
[libuevent]: https://code.google.com/p/libuevent/
|
[libuevent]: https://code.google.com/p/libuevent/
|
||||||
[Flemming Madsen]: http://www.madsensoft.dk
|
[Flemming Madsen]: http://www.madsensoft.dk
|
||||||
[Initial announcement]: http://lua-users.org/lists/lua-l/2012-03/msg00510.html
|
[Initial announcement]: http://lua-users.org/lists/lua-l/2012-03/msg00510.html
|
||||||
|
|
||||||
<!--
|
|
||||||
-- Local Variables:
|
|
||||||
-- mode: markdown
|
|
||||||
-- End:
|
|
||||||
-->
|
|
||||||
+1
-1
@@ -34,7 +34,7 @@ release-hook:
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
## Target to run when building a release
|
## Target to run when building a release
|
||||||
release: dist release-hook md5-dist
|
release: distcheck release-hook md5-dist
|
||||||
@for file in $(DIST_ARCHIVES); do \
|
@for file in $(DIST_ARCHIVES); do \
|
||||||
printf "$$file \tDistribution tarball\n"; \
|
printf "$$file \tDistribution tarball\n"; \
|
||||||
printf "$$file.md5\t"; cat $$file.md5 | cut -f1 -d' '; \
|
printf "$$file.md5\t"; cat $$file.md5 | cut -f1 -d' '; \
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ libuEv | Simple event loop for Linux
|
|||||||
* [Origin & References](#origin--references)
|
* [Origin & References](#origin--references)
|
||||||
|
|
||||||
|
|
||||||
> “Event driven software improves concurrency” -- [Dave Zarzycki, Apple][]
|
> **NOTE:** Incompatible failure mode changes in v2.0 compared to v1.x!
|
||||||
|
|
||||||
Introduction
|
Introduction
|
||||||
------------
|
------------
|
||||||
@@ -25,8 +25,8 @@ Introduction
|
|||||||
*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.
|
small size overhead impact of the library.
|
||||||
|
|
||||||
Experienced developers may appreciate that [libuEv][] is built on top of
|
Failure mode changes introduced in v2.0 may affect users of v1.x, See
|
||||||
modern Linux APIs: epoll, timerfd and signalfd.
|
the [ChangeLog][] for the full details.
|
||||||
|
|
||||||
|
|
||||||
Example
|
Example
|
||||||
@@ -49,7 +49,8 @@ int main(void)
|
|||||||
uev_ctx_t ctx;
|
uev_ctx_t ctx;
|
||||||
|
|
||||||
uev_init(&ctx);
|
uev_init(&ctx);
|
||||||
uev_timer_init(&ctx, &timer, cb, NULL, 2 * 1000, 0);
|
/* Set up a timer watcher to call cb() every other second */
|
||||||
|
uev_timer_init(&ctx, &timer, cb, NULL, 0, 2 * 1000);
|
||||||
|
|
||||||
return uev_run(&ctx, 0);
|
return uev_run(&ctx, 0);
|
||||||
}
|
}
|
||||||
@@ -78,11 +79,10 @@ The resulting .so file is ~14 kiB.
|
|||||||
Origin & References
|
Origin & References
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
[libuEv][] was originally based on [LibUEvent][8] by [Flemming Madsen][]
|
[libuEv][] originates from [LibUEvent][8] by [Flemming Madsen][], but
|
||||||
but has been completely rewritten to provide a cleaner API. It is now
|
with a rewritten and much cleaner API. It is now more similar to the
|
||||||
more similar to the famous [libev][2] by [Mark Lehmann][]. Another
|
famous [libev][2] by [Mark Lehmann][]. Another library inspiring this
|
||||||
small event library used for inspiration is the very small [picoev][9]
|
project is [picoev][9] by [Oku Kazuho][].
|
||||||
by [Oku Kazuho][].
|
|
||||||
|
|
||||||
[libuEv][] is developed and maintained by [Joachim Nilsson][]. It is
|
[libuEv][] is developed and maintained by [Joachim Nilsson][]. It is
|
||||||
built for and developed on GNU/Linux systems, patches to support *BSD
|
built for and developed on GNU/Linux systems, patches to support *BSD
|
||||||
@@ -94,6 +94,7 @@ and its [kqueue][] interface are most welcome.
|
|||||||
[3]: http://unix.com/man-page/All/3x/XtDispatchEvent
|
[3]: http://unix.com/man-page/All/3x/XtDispatchEvent
|
||||||
[8]: http://code.google.com/p/libuevent/
|
[8]: http://code.google.com/p/libuevent/
|
||||||
[9]: https://github.com/kazuho/picoev
|
[9]: https://github.com/kazuho/picoev
|
||||||
|
[ChangeLog]: https://github.com/troglobit/libuev/blob/master/ChangeLog.md
|
||||||
[Travis]: https://travis-ci.org/troglobit/libuev
|
[Travis]: https://travis-ci.org/troglobit/libuev
|
||||||
[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
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
AC_INIT(libuev, 1.6.0, https://github.com/troglobit/libuev/issues)
|
AC_INIT(libuev, 2.0.0, https://github.com/troglobit/libuev/issues)
|
||||||
AM_INIT_AUTOMAKE([1.11 foreign no-dist-gzip dist-xz])
|
AM_INIT_AUTOMAKE([1.11 foreign no-dist-gzip dist-xz])
|
||||||
AM_SILENT_RULES([yes])
|
AM_SILENT_RULES([yes])
|
||||||
|
|
||||||
|
|||||||
Vendored
+13
@@ -1,3 +1,16 @@
|
|||||||
|
libuev (2.0.0-1) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Major new upstream version, possibly incompatible changes to both
|
||||||
|
uev_run() and how watchers are called in various failure modes.
|
||||||
|
|
||||||
|
- uev_run() no longer exits the main event loop if an unrecoverable
|
||||||
|
error with a watcher occurs. Instead, the watcher is disabled and
|
||||||
|
the callback is run one last time with events set to UEV_ERROR.
|
||||||
|
- Watcher callbacks must handle UEV_ERROR conditions. This pertains
|
||||||
|
in particular to signal and timer watchers.
|
||||||
|
|
||||||
|
-- Joachim Nilsson <troglobit@gmail.com> Sat, 11 Nov 2017 16:31:46 +0100
|
||||||
|
|
||||||
libuev (1.6.0-1) unstable; urgency=medium
|
libuev (1.6.0-1) unstable; urgency=medium
|
||||||
|
|
||||||
* Support for edge triggered and oneshot event types
|
* Support for edge triggered and oneshot event types
|
||||||
|
|||||||
@@ -2,3 +2,4 @@ joystick
|
|||||||
signal
|
signal
|
||||||
cronrun
|
cronrun
|
||||||
test
|
test
|
||||||
|
redirect
|
||||||
@@ -1,5 +1,3 @@
|
|||||||
noinst_PROGRAMS = joystick
|
noinst_PROGRAMS = joystick redirect
|
||||||
AM_CPPFLAGS = -I$(top_srcdir)
|
AM_CPPFLAGS = -I$(top_srcdir)/src
|
||||||
AM_LDFLAGS = -L$(top_srcdir)
|
LDADD = $(top_srcdir)/src/libuev.la
|
||||||
LIBS = $(LTLIBINTL)
|
|
||||||
LDADD = $(top_srcdir)/libuev.la
|
|
||||||
@@ -37,8 +37,15 @@ struct js_event {
|
|||||||
uint8_t number; /* axis/button number */
|
uint8_t number; /* axis/button number */
|
||||||
} e;
|
} e;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Always check for UEV_ERROR in watcher callback!
|
||||||
|
* Possibly joystick was unplugged
|
||||||
|
*/
|
||||||
static void joystick_cb(uev_t *w, void *arg, int events)
|
static void joystick_cb(uev_t *w, void *arg, int events)
|
||||||
{
|
{
|
||||||
|
if (UEV_ERROR == events)
|
||||||
|
errx(EBADF, "Unrecoverable error, exiting");
|
||||||
|
|
||||||
if (read(w->fd, &e, sizeof(e)) < 0)
|
if (read(w->fd, &e, sizeof(e)) < 0)
|
||||||
errx(errno, "Failed reading joystick event");
|
errx(errno, "Failed reading joystick event");
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,67 @@
|
|||||||
|
/* Example of how to handle stdin redirect
|
||||||
|
*
|
||||||
|
* The problem is non-trivial since Linux epoll, which libuEv uses, does
|
||||||
|
* not support I/O watchers for regular files or directories.
|
||||||
|
*
|
||||||
|
* This works:
|
||||||
|
* echo foo | redirect
|
||||||
|
* This doesn't:
|
||||||
|
* redirect < foo.txt
|
||||||
|
*
|
||||||
|
* However, with a little bit of hacking libuEv can be made to handle
|
||||||
|
* reading from stdin as a special case.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <err.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "src/uev.h"
|
||||||
|
|
||||||
|
void process_stdin(uev_t *w, void *arg, int events)
|
||||||
|
{
|
||||||
|
char buf[256];
|
||||||
|
int len;
|
||||||
|
|
||||||
|
if (UEV_ERROR == events)
|
||||||
|
errx(EBADF, "Unrecoverable error, exiting");
|
||||||
|
|
||||||
|
len = read(w->fd, buf, sizeof(buf));
|
||||||
|
if (len == -1) {
|
||||||
|
warn("Error reading from stdin");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len == 0) {
|
||||||
|
warnx("Connection closed.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Read %d bytes\n", len);
|
||||||
|
if (write(STDOUT_FILENO, buf, len) != len)
|
||||||
|
warn("Failed writing to stdout");
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
uev_t watcher;
|
||||||
|
uev_ctx_t ctx;
|
||||||
|
|
||||||
|
uev_init(&ctx);
|
||||||
|
|
||||||
|
ret = uev_io_init(&ctx, &watcher, process_stdin, NULL, STDIN_FILENO, UEV_READ);
|
||||||
|
if (ret)
|
||||||
|
err(errno, "Failed setting up STDIN watcher");
|
||||||
|
|
||||||
|
return uev_run(&ctx, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Local Variables:
|
||||||
|
* compile-command: "make redirect; echo hej > hej.txt; ./redirect < hej.txt"
|
||||||
|
* indent-tabs-mode: t
|
||||||
|
* c-file-style: "linux"
|
||||||
|
* End:
|
||||||
|
*/
|
||||||
+1
-1
@@ -2,7 +2,7 @@ lib_LTLIBRARIES = libuev.la
|
|||||||
libuev_la_SOURCES = uev.c io.c timer.c signal.c cron.c
|
libuev_la_SOURCES = uev.c io.c timer.c signal.c cron.c
|
||||||
libuev_la_CPPFLAGS = -D_GNU_SOURCE -D_TIME_BITS=64
|
libuev_la_CPPFLAGS = -D_GNU_SOURCE -D_TIME_BITS=64
|
||||||
libuev_la_CFLAGS = -W -Wall -Wextra
|
libuev_la_CFLAGS = -W -Wall -Wextra
|
||||||
libuev_la_LDFLAGS = $(AM_LDFLAGS) -version-info 1:2:0
|
libuev_la_LDFLAGS = $(AM_LDFLAGS) -version-info 2:0:0
|
||||||
|
|
||||||
noinst_PROGRAMS = bench
|
noinst_PROGRAMS = bench
|
||||||
bench_CPPFLAGS = -D_GNU_SOURCE
|
bench_CPPFLAGS = -D_GNU_SOURCE
|
||||||
|
|||||||
+3
-3
@@ -72,11 +72,11 @@ int uev_cron_init(uev_ctx_t *ctx, uev_t *w, uev_cb_t *cb, void *arg, time_t when
|
|||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (uev_watcher_init(ctx, w, UEV_CRON_TYPE, cb, arg, fd, UEV_READ))
|
if (_uev_watcher_init(ctx, w, UEV_CRON_TYPE, cb, arg, fd, UEV_READ))
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
if (uev_cron_set(w, when, interval)) {
|
if (uev_cron_set(w, when, interval)) {
|
||||||
uev_watcher_stop(w);
|
_uev_watcher_stop(w);
|
||||||
exit:
|
exit:
|
||||||
close(fd);
|
close(fd);
|
||||||
return -1;
|
return -1;
|
||||||
@@ -132,7 +132,7 @@ int uev_cron_set(uev_t *w, time_t when, time_t interval)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return uev_watcher_start(w);
|
return _uev_watcher_start(w);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -44,10 +44,10 @@ int uev_io_init(uev_ctx_t *ctx, uev_t *w, uev_cb_t *cb, void *arg, int fd, int e
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uev_watcher_init(ctx, w, UEV_IO_TYPE, cb, arg, fd, events))
|
if (_uev_watcher_init(ctx, w, UEV_IO_TYPE, cb, arg, fd, events))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return uev_watcher_start(w);
|
return _uev_watcher_start(w);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -61,8 +61,8 @@ int uev_io_init(uev_ctx_t *ctx, uev_t *w, uev_cb_t *cb, void *arg, int fd, int e
|
|||||||
int uev_io_set(uev_t *w, int fd, int events)
|
int uev_io_set(uev_t *w, int fd, int events)
|
||||||
{
|
{
|
||||||
|
|
||||||
if ((events & UEV_ONESHOT) && w->active)
|
if ((events & UEV_ONESHOT) && _uev_watcher_active(w))
|
||||||
return uev_watcher_rearm(w);
|
return _uev_watcher_rearm(w);
|
||||||
|
|
||||||
/* Ignore any errors, only to clean up anything lingering ... */
|
/* Ignore any errors, only to clean up anything lingering ... */
|
||||||
uev_io_stop(w);
|
uev_io_stop(w);
|
||||||
@@ -89,7 +89,7 @@ int uev_io_start(uev_t *w)
|
|||||||
*/
|
*/
|
||||||
int uev_io_stop(uev_t *w)
|
int uev_io_stop(uev_t *w)
|
||||||
{
|
{
|
||||||
return uev_watcher_stop(w);
|
return _uev_watcher_stop(w);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+9
-8
@@ -38,7 +38,7 @@ typedef enum {
|
|||||||
} uev_type_t;
|
} uev_type_t;
|
||||||
|
|
||||||
/* Event mask, used internally only. */
|
/* Event mask, used internally only. */
|
||||||
#define UEV_EVENT_MASK (UEV_READ | UEV_WRITE | UEV_PRI | UEV_HUP | UEV_RDHUP | UEV_EDGE | UEV_ONESHOT)
|
#define UEV_EVENT_MASK (UEV_ERROR | UEV_READ | UEV_WRITE | UEV_PRI | UEV_HUP | UEV_RDHUP | UEV_EDGE | UEV_ONESHOT)
|
||||||
|
|
||||||
/* Main libuEv context type */
|
/* Main libuEv context type */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -46,6 +46,7 @@ typedef struct {
|
|||||||
int fd; /* For epoll() */
|
int fd; /* For epoll() */
|
||||||
uint32_t errors;
|
uint32_t errors;
|
||||||
LIST_HEAD(,uev) watchers;
|
LIST_HEAD(,uev) watchers;
|
||||||
|
uint32_t workaround; /* For workarounds, e.g. redirected stdin */
|
||||||
} uev_ctx_t;
|
} uev_ctx_t;
|
||||||
|
|
||||||
/* Forward declare due to dependencys, don't try this at home kids. */
|
/* Forward declare due to dependencys, don't try this at home kids. */
|
||||||
@@ -81,13 +82,13 @@ struct uev;
|
|||||||
uev_type_t
|
uev_type_t
|
||||||
|
|
||||||
/* Internal API for dealing with generic watchers */
|
/* Internal API for dealing with generic watchers */
|
||||||
int uev_watcher_init (uev_ctx_t *ctx, struct uev *w, uev_type_t type,
|
int _uev_watcher_init (uev_ctx_t *ctx, struct uev *w, uev_type_t type,
|
||||||
void (*cb)(struct uev *, void *, int), void *arg,
|
void (*cb)(struct uev *, void *, int), void *arg,
|
||||||
int fd, int events);
|
int fd, int events);
|
||||||
int uev_watcher_start (struct uev *w);
|
int _uev_watcher_start (struct uev *w);
|
||||||
int uev_watcher_stop (struct uev *w);
|
int _uev_watcher_stop (struct uev *w);
|
||||||
int uev_watcher_active(struct uev *w);
|
int _uev_watcher_active(struct uev *w);
|
||||||
int uev_watcher_rearm (struct uev *w);
|
int _uev_watcher_rearm (struct uev *w);
|
||||||
|
|
||||||
#endif /* LIBUEV_PRIVATE_H_ */
|
#endif /* LIBUEV_PRIVATE_H_ */
|
||||||
|
|
||||||
|
|||||||
+4
-4
@@ -56,11 +56,11 @@ int uev_signal_init(uev_ctx_t *ctx, uev_t *w, uev_cb_t *cb, void *arg, int signo
|
|||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (uev_watcher_init(ctx, w, UEV_SIGNAL_TYPE, cb, arg, fd, UEV_READ))
|
if (_uev_watcher_init(ctx, w, UEV_SIGNAL_TYPE, cb, arg, fd, UEV_READ))
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
if (uev_signal_set(w, signo)) {
|
if (uev_signal_set(w, signo)) {
|
||||||
uev_watcher_stop(w);
|
_uev_watcher_stop(w);
|
||||||
exit:
|
exit:
|
||||||
close(fd);
|
close(fd);
|
||||||
return -1;
|
return -1;
|
||||||
@@ -109,7 +109,7 @@ int uev_signal_set(uev_t *w, int signo)
|
|||||||
if (signalfd(w->fd, &mask, SFD_NONBLOCK) < 0)
|
if (signalfd(w->fd, &mask, SFD_NONBLOCK) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return uev_watcher_start(w);
|
return _uev_watcher_start(w);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -140,7 +140,7 @@ int uev_signal_start(uev_t *w)
|
|||||||
*/
|
*/
|
||||||
int uev_signal_stop(uev_t *w)
|
int uev_signal_stop(uev_t *w)
|
||||||
{
|
{
|
||||||
if (uev_watcher_stop(w))
|
if (_uev_watcher_stop(w))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
close(w->fd);
|
close(w->fd);
|
||||||
|
|||||||
+5
-5
@@ -76,11 +76,11 @@ int uev_timer_init(uev_ctx_t *ctx, uev_t *w, uev_cb_t *cb, void *arg, int timeou
|
|||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (uev_watcher_init(ctx, w, UEV_TIMER_TYPE, cb, arg, fd, UEV_READ))
|
if (_uev_watcher_init(ctx, w, UEV_TIMER_TYPE, cb, arg, fd, UEV_READ))
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
if (uev_timer_set(w, timeout, period)) {
|
if (uev_timer_set(w, timeout, period)) {
|
||||||
uev_watcher_stop(w);
|
_uev_watcher_stop(w);
|
||||||
exit:
|
exit:
|
||||||
close(fd);
|
close(fd);
|
||||||
return -1;
|
return -1;
|
||||||
@@ -135,7 +135,7 @@ int uev_timer_set(uev_t *w, int timeout, int period)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return uev_watcher_start(w);
|
return _uev_watcher_start(w);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -152,7 +152,7 @@ int uev_timer_start(uev_t *w)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (-1 != w->fd)
|
if (-1 != w->fd)
|
||||||
uev_watcher_stop(w);
|
_uev_watcher_stop(w);
|
||||||
|
|
||||||
return uev_timer_set(w, w->u.t.timeout, w->u.t.period);
|
return uev_timer_set(w, w->u.t.timeout, w->u.t.period);
|
||||||
}
|
}
|
||||||
@@ -168,7 +168,7 @@ int uev_timer_stop(uev_t *w)
|
|||||||
/* Stop kernel timer */
|
/* Stop kernel timer */
|
||||||
uev_timer_set(w, 0, 0);
|
uev_timer_set(w, 0, 0);
|
||||||
|
|
||||||
if (uev_watcher_stop(w))
|
if (_uev_watcher_stop(w))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* Close timerfd, will have to be reopened again on reset */
|
/* Close timerfd, will have to be reopened again on reset */
|
||||||
|
|||||||
@@ -26,6 +26,8 @@
|
|||||||
#include <fcntl.h> /* O_CLOEXEC */
|
#include <fcntl.h> /* O_CLOEXEC */
|
||||||
#include <string.h> /* memset() */
|
#include <string.h> /* memset() */
|
||||||
#include <sys/epoll.h>
|
#include <sys/epoll.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/select.h> /* for select() workaround */
|
||||||
#include <sys/signalfd.h> /* struct signalfd_siginfo */
|
#include <sys/signalfd.h> /* struct signalfd_siginfo */
|
||||||
#include <unistd.h> /* close(), read() */
|
#include <unistd.h> /* close(), read() */
|
||||||
|
|
||||||
@@ -56,8 +58,32 @@ static int is_valid_fd(int fd)
|
|||||||
return fcntl(fd, F_GETFL) != -1 || errno != EBADF;
|
return fcntl(fd, F_GETFL) != -1 || errno != EBADF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Used by file i/o workaround when epoll => EPERM */
|
||||||
|
static int has_data(int fd)
|
||||||
|
{
|
||||||
|
struct timeval timeout = { 0, 0 };
|
||||||
|
fd_set fds;
|
||||||
|
int n = 0;
|
||||||
|
|
||||||
|
FD_ZERO(&fds);
|
||||||
|
FD_SET(fd, &fds);
|
||||||
|
|
||||||
|
if (select(1, &fds, NULL, NULL, &timeout) > 0)
|
||||||
|
return ioctl(0, FIONREAD, &n) == 0 && n > 0;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set error condition and remove watcher from set */
|
||||||
|
static void invalidate_watcher(uev_t *w, struct epoll_event *event)
|
||||||
|
{
|
||||||
|
event->events = UEV_ERROR;
|
||||||
|
w->active = 0;
|
||||||
|
LIST_REMOVE(w, link);
|
||||||
|
}
|
||||||
|
|
||||||
/* Private to libuEv, do not use directly! */
|
/* Private to libuEv, do not use directly! */
|
||||||
int uev_watcher_init(uev_ctx_t *ctx, uev_t *w, uev_type_t type, uev_cb_t *cb, void *arg, int fd, int events)
|
int _uev_watcher_init(uev_ctx_t *ctx, uev_t *w, uev_type_t type, uev_cb_t *cb, void *arg, int fd, int events)
|
||||||
{
|
{
|
||||||
if (!ctx || !w) {
|
if (!ctx || !w) {
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
@@ -76,7 +102,7 @@ int uev_watcher_init(uev_ctx_t *ctx, uev_t *w, uev_type_t type, uev_cb_t *cb, vo
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Private to libuEv, do not use directly! */
|
/* Private to libuEv, do not use directly! */
|
||||||
int uev_watcher_start(uev_t *w)
|
int _uev_watcher_start(uev_t *w)
|
||||||
{
|
{
|
||||||
struct epoll_event ev;
|
struct epoll_event ev;
|
||||||
|
|
||||||
@@ -85,15 +111,28 @@ int uev_watcher_start(uev_t *w)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (w->active)
|
if (_uev_watcher_active(w))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ev.events = w->events | EPOLLRDHUP;
|
ev.events = w->events | EPOLLRDHUP;
|
||||||
ev.data.ptr = w;
|
ev.data.ptr = w;
|
||||||
if (epoll_ctl(w->ctx->fd, EPOLL_CTL_ADD, w->fd, &ev) < 0)
|
if (epoll_ctl(w->ctx->fd, EPOLL_CTL_ADD, w->fd, &ev) < 0) {
|
||||||
return -1;
|
if (errno != EPERM)
|
||||||
|
return -1;
|
||||||
|
|
||||||
w->active = 1;
|
/* Handle special case: `application < file.txt` */
|
||||||
|
if (w->type != UEV_IO_TYPE || w->events != UEV_READ)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* Only allow this special handling for stdin */
|
||||||
|
if (w->fd != STDIN_FILENO)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
w->ctx->workaround = 1;
|
||||||
|
w->active = -1;
|
||||||
|
} else {
|
||||||
|
w->active = 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Add to internal list for bookkeeping */
|
/* Add to internal list for bookkeeping */
|
||||||
LIST_INSERT_HEAD(&w->ctx->watchers, w, link);
|
LIST_INSERT_HEAD(&w->ctx->watchers, w, link);
|
||||||
@@ -102,14 +141,14 @@ int uev_watcher_start(uev_t *w)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Private to libuEv, do not use directly! */
|
/* Private to libuEv, do not use directly! */
|
||||||
int uev_watcher_stop(uev_t *w)
|
int _uev_watcher_stop(uev_t *w)
|
||||||
{
|
{
|
||||||
if (!w) {
|
if (!w) {
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!w->active)
|
if (!_uev_watcher_active(w))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
w->active = 0;
|
w->active = 0;
|
||||||
@@ -125,16 +164,16 @@ int uev_watcher_stop(uev_t *w)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Private to libuEv, do not use directly! */
|
/* Private to libuEv, do not use directly! */
|
||||||
int uev_watcher_active(uev_t *w)
|
int _uev_watcher_active(uev_t *w)
|
||||||
{
|
{
|
||||||
if (!w)
|
if (!w)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return w->active;
|
return w->active > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Private to libuEv, do not use directly! */
|
/* Private to libuEv, do not use directly! */
|
||||||
int uev_watcher_rearm(uev_t *w)
|
int _uev_watcher_rearm(uev_t *w)
|
||||||
{
|
{
|
||||||
struct epoll_event ev;
|
struct epoll_event ev;
|
||||||
|
|
||||||
@@ -189,7 +228,7 @@ int uev_exit(uev_ctx_t *ctx)
|
|||||||
/* Remove from internal list */
|
/* Remove from internal list */
|
||||||
LIST_REMOVE(w, link);
|
LIST_REMOVE(w, link);
|
||||||
|
|
||||||
if (!w->active)
|
if (!_uev_watcher_active(w))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
switch (w->type) {
|
switch (w->type) {
|
||||||
@@ -231,7 +270,7 @@ int uev_exit(uev_ctx_t *ctx)
|
|||||||
*/
|
*/
|
||||||
int uev_run(uev_ctx_t *ctx, int flags)
|
int uev_run(uev_ctx_t *ctx, int flags)
|
||||||
{
|
{
|
||||||
int result = 0, timeout = -1;
|
int timeout = -1;
|
||||||
uev_t *w;
|
uev_t *w;
|
||||||
|
|
||||||
if (!ctx || ctx->fd < 0) {
|
if (!ctx || ctx->fd < 0) {
|
||||||
@@ -253,10 +292,30 @@ int uev_run(uev_ctx_t *ctx, int flags)
|
|||||||
uev_timer_set(w, w->u.t.timeout, w->u.t.period);
|
uev_timer_set(w, w->u.t.timeout, w->u.t.period);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (ctx->running) {
|
while (ctx->running && !LIST_EMPTY(&ctx->watchers)) {
|
||||||
int i, nfds;
|
int i, nfds, rerun = 0;
|
||||||
struct epoll_event events[UEV_MAX_EVENTS];
|
struct epoll_event events[UEV_MAX_EVENTS];
|
||||||
|
|
||||||
|
/* Handle special case: `application < file.txt` */
|
||||||
|
if (ctx->workaround) {
|
||||||
|
LIST_FOREACH(w, &ctx->watchers, link) {
|
||||||
|
if (w->active != -1 || !w->cb)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!has_data(w->fd)) {
|
||||||
|
w->active = 0;
|
||||||
|
LIST_REMOVE(w, link);
|
||||||
|
}
|
||||||
|
|
||||||
|
rerun++;
|
||||||
|
w->cb(w, w->arg, UEV_READ);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rerun)
|
||||||
|
continue;
|
||||||
|
ctx->workaround = 0;
|
||||||
|
|
||||||
while ((nfds = epoll_wait(ctx->fd, events, UEV_MAX_EVENTS, timeout)) < 0) {
|
while ((nfds = epoll_wait(ctx->fd, events, UEV_MAX_EVENTS, timeout)) < 0) {
|
||||||
if (!ctx->running)
|
if (!ctx->running)
|
||||||
break;
|
break;
|
||||||
@@ -266,7 +325,7 @@ int uev_run(uev_ctx_t *ctx, int flags)
|
|||||||
|
|
||||||
/* Unrecoverable error, cleanup and exit with error. */
|
/* Unrecoverable error, cleanup and exit with error. */
|
||||||
uev_exit(ctx);
|
uev_exit(ctx);
|
||||||
return -1;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; ctx->running && i < nfds; i++) {
|
for (i = 0; ctx->running && i < nfds; i++) {
|
||||||
@@ -280,23 +339,24 @@ int uev_run(uev_ctx_t *ctx, int flags)
|
|||||||
|
|
||||||
/* If not valid anymore, try to remove, ignore any errors. */
|
/* If not valid anymore, try to remove, ignore any errors. */
|
||||||
if (!is_valid_fd(w->fd))
|
if (!is_valid_fd(w->fd))
|
||||||
uev_watcher_stop(w);
|
_uev_watcher_stop(w);
|
||||||
|
|
||||||
/* Must recreate epoll fd now ... */
|
/* Must recreate epoll fd now ... */
|
||||||
if (_init(ctx, 1)) {
|
if (_init(ctx, 1)) {
|
||||||
|
/* Catastrophic error, no way to recover. */
|
||||||
uev_exit(ctx);
|
uev_exit(ctx);
|
||||||
return -2;
|
return -3;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Restart watchers in new efd */
|
/* Restart watchers in new efd */
|
||||||
LIST_FOREACH_SAFE(w, &ctx->watchers, link, tmp) {
|
LIST_FOREACH_SAFE(w, &ctx->watchers, link, tmp) {
|
||||||
if (w->active) {
|
if (_uev_watcher_active(w)) {
|
||||||
w->active = 0;
|
w->active = 0;
|
||||||
LIST_REMOVE(w, link);
|
LIST_REMOVE(w, link);
|
||||||
uev_watcher_start(w);
|
_uev_watcher_start(w);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
uev_watcher_start(retry);
|
_uev_watcher_start(retry);
|
||||||
|
|
||||||
/* New efd, restart everything! */
|
/* New efd, restart everything! */
|
||||||
ctx->errors = 0;
|
ctx->errors = 0;
|
||||||
@@ -308,12 +368,10 @@ int uev_run(uev_ctx_t *ctx, int flags)
|
|||||||
uint64_t exp;
|
uint64_t exp;
|
||||||
|
|
||||||
if (read(w->fd, &exp, sizeof(exp)) != sizeof(exp)) {
|
if (read(w->fd, &exp, sizeof(exp)) != sizeof(exp)) {
|
||||||
if (errno != ECANCELED) {
|
if (errno != ECANCELED)
|
||||||
uev_exit(ctx);
|
invalidate_watcher(w, &events[i]);
|
||||||
return -3;
|
else
|
||||||
}
|
events[i].events = UEV_HUP;
|
||||||
|
|
||||||
events[i].events = UEV_HUP;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!w->u.c.interval)
|
if (!w->u.c.interval)
|
||||||
@@ -326,8 +384,7 @@ int uev_run(uev_ctx_t *ctx, int flags)
|
|||||||
uint64_t exp;
|
uint64_t exp;
|
||||||
|
|
||||||
if (read(w->fd, &exp, sizeof(exp)) != sizeof(exp)) {
|
if (read(w->fd, &exp, sizeof(exp)) != sizeof(exp)) {
|
||||||
uev_exit(ctx);
|
invalidate_watcher(w, &events[i]);
|
||||||
return -3;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!w->u.t.period)
|
if (!w->u.t.period)
|
||||||
@@ -338,10 +395,8 @@ int uev_run(uev_ctx_t *ctx, int flags)
|
|||||||
struct signalfd_siginfo fdsi;
|
struct signalfd_siginfo fdsi;
|
||||||
ssize_t sz = sizeof(fdsi);
|
ssize_t sz = sizeof(fdsi);
|
||||||
|
|
||||||
if (read(w->fd, &fdsi, sz) != sz) {
|
if (read(w->fd, &fdsi, sz) != sz)
|
||||||
uev_exit(ctx);
|
invalidate_watcher(w, &events[i]);
|
||||||
return -4;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (w->cb)
|
if (w->cb)
|
||||||
@@ -357,11 +412,11 @@ int uev_run(uev_ctx_t *ctx, int flags)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((flags & UEV_ONCE) || LIST_EMPTY(&ctx->watchers))
|
if (flags & UEV_ONCE)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -32,6 +32,7 @@
|
|||||||
|
|
||||||
/* I/O events, signal and timer revents are always UEV_READ */
|
/* I/O events, signal and timer revents are always UEV_READ */
|
||||||
#define UEV_NONE 0
|
#define UEV_NONE 0
|
||||||
|
#define UEV_ERROR EPOLLERR
|
||||||
#define UEV_READ EPOLLIN
|
#define UEV_READ EPOLLIN
|
||||||
#define UEV_WRITE EPOLLOUT
|
#define UEV_WRITE EPOLLOUT
|
||||||
#define UEV_PRI EPOLLPRI
|
#define UEV_PRI EPOLLPRI
|
||||||
@@ -45,10 +46,10 @@
|
|||||||
#define UEV_NONBLOCK 2
|
#define UEV_NONBLOCK 2
|
||||||
|
|
||||||
/* Macros */
|
/* Macros */
|
||||||
#define uev_io_active(w) uev_watcher_active(w)
|
#define uev_io_active(w) _uev_watcher_active(w)
|
||||||
#define uev_timer_active(w) uev_watcher_active(w)
|
#define uev_timer_active(w) _uev_watcher_active(w)
|
||||||
#define uev_cron_active(w) uev_watcher_active(w)
|
#define uev_cron_active(w) _uev_watcher_active(w)
|
||||||
#define uev_signal_active(w) uev_watcher_active(w)
|
#define uev_signal_active(w) _uev_watcher_active(w)
|
||||||
|
|
||||||
/* Event watcher */
|
/* Event watcher */
|
||||||
typedef struct uev {
|
typedef struct uev {
|
||||||
|
|||||||
Reference in new issue
Block a user