mirror of
https://github.com/troglobit/libuev.git
synced 2026-10-23 11:24:34 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2e6fac00bb | ||
|
|
8a3ab17435 | ||
|
|
aa62e60137 | ||
|
|
69c5b7f538 | ||
|
|
e765e42eb9 | ||
|
|
56a2e7ff30 | ||
|
|
b6f92e2b15 | ||
|
|
604afc6cec | ||
|
|
73ae8ba098 | ||
|
|
6a19fa7e93 | ||
|
|
737ceb4398 | ||
|
|
a8798ea6a7 | ||
|
|
d976171a14 | ||
|
|
398251ade6 | ||
|
|
628565b746 | ||
|
|
de4d969ca0 | ||
|
|
389c3b27ab | ||
|
|
03a29440ef | ||
|
|
9b3af80082 | ||
|
|
8f2c9f7f0e | ||
|
|
6a21b7a90b | ||
|
|
847532f935 | ||
|
|
ec1290a46e | ||
|
|
3bee117a85 | ||
|
|
75f59b7b11 | ||
|
|
59e1d376db | ||
|
|
52d8d7109b | ||
|
|
7e38c11b87 | ||
|
|
e5bc49a8e6 | ||
|
|
1f6fa93314 | ||
|
|
fe9b7264d0 | ||
|
|
6447c74722 | ||
|
|
f2148d41a4 | ||
|
|
0cb4416280 | ||
|
|
4255ebb9c6 | ||
|
|
930cce21fa | ||
|
|
addd60db22 | ||
|
|
e3d40ef010 | ||
|
|
618b50ee88 | ||
|
|
f64301194a | ||
|
|
bdbfe809ab | ||
|
|
2742adfe98 | ||
|
|
35d3a0f185 | ||
|
|
441d53e46e | ||
|
|
0b19880f80 | ||
|
|
852bd506e8 | ||
|
|
98c8e9f8b1 | ||
|
|
9fc5227343 | ||
|
|
e613248392 | ||
|
|
ac5f01ea22 | ||
|
|
a0ddb4eae3 | ||
|
|
1e7720735f | ||
|
|
8010d76133 | ||
|
|
73459ca609 |
No files matched your search
+2
-1
@@ -6,6 +6,7 @@
|
|||||||
*.a
|
*.a
|
||||||
*.la
|
*.la
|
||||||
*.lo
|
*.lo
|
||||||
|
*.html
|
||||||
.deps
|
.deps
|
||||||
.libs
|
.libs
|
||||||
compile
|
compile
|
||||||
@@ -23,7 +24,7 @@ aclocal.m4
|
|||||||
ar-lib
|
ar-lib
|
||||||
autom4te.cache
|
autom4te.cache
|
||||||
bench
|
bench
|
||||||
test
|
|
||||||
libuev*.tar.*
|
libuev*.tar.*
|
||||||
libuev.pc
|
libuev.pc
|
||||||
!libuev.pc.in
|
!libuev.pc.in
|
||||||
|
test-driver
|
||||||
+4
-5
@@ -2,7 +2,7 @@
|
|||||||
# Defaults to GNU GCC and autotools: ./configure && make && make test
|
# Defaults to GNU GCC and autotools: ./configure && make && make test
|
||||||
language: c
|
language: c
|
||||||
|
|
||||||
# We don't need to install packages, use dockerized build, quicker
|
# Use docker for quicker builds, it now allows https://docs.travis-ci.com/user/apt/
|
||||||
sudo: false
|
sudo: false
|
||||||
|
|
||||||
env:
|
env:
|
||||||
@@ -17,14 +17,13 @@ addons:
|
|||||||
name: "troglobit/libuev"
|
name: "troglobit/libuev"
|
||||||
description: "libuEv | Simple event loop for Linux"
|
description: "libuEv | Simple event loop for Linux"
|
||||||
notification_email: troglobit@gmail.com
|
notification_email: troglobit@gmail.com
|
||||||
build_command_prepend: "./autogen && ./configure --enable-examples"
|
build_command_prepend: "./autogen && ./configure"
|
||||||
build_command: "make clean all"
|
build_command: "make clean all"
|
||||||
branch_pattern: dev
|
branch_pattern: dev
|
||||||
|
|
||||||
# We don't use configure, so we must define our own build script.
|
|
||||||
script:
|
script:
|
||||||
- ./autogen.sh
|
- ./autogen.sh
|
||||||
- ./configure --disable-silent-rules --enable-examples
|
- ./configure --disable-silent-rules
|
||||||
- make clean
|
- make clean
|
||||||
- make -j5
|
- make -j5
|
||||||
- make test
|
- make check
|
||||||
+55
-4
@@ -3,6 +3,56 @@ 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.5.2][] - 2016-11-27
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
- Fix build regression in v1.5.1
|
||||||
|
|
||||||
|
|
||||||
|
[v1.5.1][] - 2016-11-27
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
### Changes
|
||||||
|
- Add support for checking if a watcher is active.
|
||||||
|
- Refactor unit testing framework
|
||||||
|
|
||||||
|
|
||||||
|
[v1.5.0][] - 2016-10-30
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
### Changes
|
||||||
|
- Add support for absolute timers with the `uev_cron_*()` API.
|
||||||
|
- Update build & install instructions in README
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
- Fix `uev_timer_set()` so that it returns error in case the underlying
|
||||||
|
Linux timerfd API fails.
|
||||||
|
|
||||||
|
|
||||||
|
[v1.4.2][] - 2016-06-25
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
### Changes
|
||||||
|
- Add range checks for `period` and `timeout` to `uev_timer_init()` and
|
||||||
|
`uev_timer_set()`. If either on is `< 0` libuEv now return `ERANGE`.
|
||||||
|
|
||||||
|
|
||||||
|
[v1.4.1][] - 2016-04-22
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
### Changes
|
||||||
|
- Add some `pkg-config` integration tips for developers using libuEv
|
||||||
|
with GNU autotools in their projects.
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
- Add missing `SFD_CLOEXEC` and `TFD_CLOEXEC` to signal and timer file
|
||||||
|
descriptors. This prevents these file descriptors from "leaking" into
|
||||||
|
sub-processes of the parent thread. The kernel will atomically close
|
||||||
|
these descriptors for forked-off children calling the exec*() family
|
||||||
|
of syscalls.
|
||||||
|
- Minor coding style fixes and simplification of build scripts.
|
||||||
|
|
||||||
|
|
||||||
[v1.4.0][] - 2016-03-22
|
[v1.4.0][] - 2016-03-22
|
||||||
-----------------------
|
-----------------------
|
||||||
@@ -11,12 +61,11 @@ This release changes the header file namespace, which was silently
|
|||||||
introduced in [v1.2.1][]. Apologies for any problems this may cause!
|
introduced in [v1.2.1][]. Apologies for any problems this may cause!
|
||||||
|
|
||||||
### Changes
|
### Changes
|
||||||
|
|
||||||
- Change namespace for header files: `libuev/` to `uev/`, e.g. using
|
- Change namespace for header files: `libuev/` to `uev/`, e.g. using
|
||||||
`pkg-config` your C program must now `#include <uev/uev.h>`
|
`pkg-config` your C program must now `#include <uev/uev.h>`
|
||||||
- Support for EPOLLPRI events for I/O watchers, thanks to Markus Svilans
|
- Support for `EPOLLPRI` events for I/O watchers, thanks to Markus Svilans
|
||||||
- Simplified joystick example
|
- Simplified joystick example
|
||||||
- Updated README slightly
|
- Updated `README` slightly
|
||||||
|
|
||||||
|
|
||||||
[v1.3.1][] - 2016-02-02
|
[v1.3.1][] - 2016-02-02
|
||||||
@@ -218,7 +267,9 @@ v0.0.1 - 2012-03-17
|
|||||||
Lua users mailing list.
|
Lua users mailing list.
|
||||||
|
|
||||||
|
|
||||||
[UNRELEASED]: https://github.com/troglobit/libuev/compare/v1.4.0...HEAD
|
[UNRELEASED]: https://github.com/troglobit/libuev/compare/v1.4.2...HEAD
|
||||||
|
[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.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
|
||||||
[v1.3.1]: https://github.com/troglobit/libuev/compare/v1.3.0...v1.3.1
|
[v1.3.1]: https://github.com/troglobit/libuev/compare/v1.3.0...v1.3.1
|
||||||
[v1.3.0]: https://github.com/troglobit/libuev/compare/v1.2.3...v1.3.0
|
[v1.3.0]: https://github.com/troglobit/libuev/compare/v1.2.3...v1.3.0
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
Copyright (c) 2012 Flemming Madsen <flemming!madsen()madsensoft!dk>
|
Copyright (c) 2012 Flemming Madsen <flemming!madsen()madsensoft!dk>
|
||||||
Copyright (c) 2013-2015 Joachim Nilsson <troglobit()gmail!com>
|
Copyright (c) 2013-2016 Joachim Nilsson <troglobit()gmail!com>
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
+10
-26
@@ -1,39 +1,23 @@
|
|||||||
ACLOCAL_AMFLAGS = -I m4
|
ACLOCAL_AMFLAGS = -I m4
|
||||||
|
|
||||||
lib_LTLIBRARIES = libuev.la
|
lib_LTLIBRARIES = libuev.la
|
||||||
pkgincludedir = $(includedir)/uev
|
libuev_la_SOURCES = uev.c io.c timer.c signal.c cron.c
|
||||||
pkginclude_HEADERS = uev.h private.h queue.h
|
|
||||||
libuev_la_SOURCES = uev.c io.c timer.c signal.c
|
|
||||||
|
|
||||||
check_PROGRAMS = bench
|
|
||||||
bench_CPPFLAGS = -D_GNU_SOURCE
|
|
||||||
bench_LDADD = $(top_srcdir)/libuev.la
|
|
||||||
|
|
||||||
libuev_la_CPPFLAGS = -D_GNU_SOURCE
|
libuev_la_CPPFLAGS = -D_GNU_SOURCE
|
||||||
libuev_la_CFLAGS = -W -Wall -Wextra
|
libuev_la_CFLAGS = -W -Wall -Wextra
|
||||||
libuev_la_LDFLAGS = $(AM_LDFLAGS) -version-info 1:0:0
|
libuev_la_LDFLAGS = $(AM_LDFLAGS) -version-info 1:2:0
|
||||||
|
|
||||||
|
noinst_PROGRAMS = bench
|
||||||
|
bench_CPPFLAGS = -D_GNU_SOURCE
|
||||||
|
bench_LDADD = libuev.la
|
||||||
|
|
||||||
pkgconfigdir = $(libdir)/pkgconfig
|
pkgconfigdir = $(libdir)/pkgconfig
|
||||||
|
pkgincludedir = $(includedir)/uev
|
||||||
pkgconfig_DATA = libuev.pc
|
pkgconfig_DATA = libuev.pc
|
||||||
|
pkginclude_HEADERS = uev.h private.h queue.h
|
||||||
doc_DATA = README.md LICENSE
|
doc_DATA = README.md LICENSE
|
||||||
EXTRA_DIST = README.md LICENSE AUTHORS ChangeLog.md
|
EXTRA_DIST = README.md LICENSE AUTHORS ChangeLog.md
|
||||||
|
DIST_SUBDIRS = examples tests
|
||||||
DIST_SUBDIRS = examples
|
SUBDIRS = tests
|
||||||
SUBDIRS = .
|
|
||||||
if ENABLE_EXAMPLES
|
|
||||||
SUBDIRS += examples
|
|
||||||
endif
|
|
||||||
|
|
||||||
test joystick: all-recursive
|
|
||||||
./examples/$@
|
|
||||||
|
|
||||||
check-local:
|
|
||||||
@echo " BENCH $(PACKAGE)"
|
|
||||||
@./bench
|
|
||||||
if ENABLE_EXAMPLES
|
|
||||||
@echo " TEST $(PACKAGE)"
|
|
||||||
@./examples/test
|
|
||||||
endif
|
|
||||||
|
|
||||||
## Generate MD5 checksum file
|
## Generate MD5 checksum file
|
||||||
MD5 = md5sum
|
MD5 = md5sum
|
||||||
|
|||||||
@@ -3,9 +3,6 @@ libuEv | Simple event loop for Linux
|
|||||||
[![Travis Status][]][Travis] [![Coverity Status][]][Coverity Scan]
|
[![Travis Status][]][Travis] [![Coverity Status][]][Coverity Scan]
|
||||||
|
|
||||||
|
|
||||||
Table of Contents
|
|
||||||
-----------------
|
|
||||||
|
|
||||||
* [Introduction](#introduction)
|
* [Introduction](#introduction)
|
||||||
* [API](#api)
|
* [API](#api)
|
||||||
* [Create an Event Context](#create-an-event-context)
|
* [Create an Event Context](#create-an-event-context)
|
||||||
@@ -15,50 +12,22 @@ Table of Contents
|
|||||||
* [Using -luev](#using--luev)
|
* [Using -luev](#using--luev)
|
||||||
* [Joystick Example](#joystick-example)
|
* [Joystick Example](#joystick-example)
|
||||||
* [Build & Install](#build--install)
|
* [Build & Install](#build--install)
|
||||||
|
* [Background](#background)
|
||||||
* [Origin & References](#origin--references)
|
* [Origin & References](#origin--references)
|
||||||
|
|
||||||
|
|
||||||
Introduction
|
Introduction
|
||||||
------------
|
------------
|
||||||
|
|
||||||
> “Why an event loop, why not use threads?”
|
|
||||||
|
|
||||||
With the advent of light-weight processes (threads) programmers these
|
|
||||||
days have a [golden hammer](http://c2.com/cgi/wiki?GoldenHammer) they
|
|
||||||
often swing without consideration. Event loops and non-blocking I/O is
|
|
||||||
often a far easier approach, as well as less error prone.
|
|
||||||
|
|
||||||
The purpose of many applications is, with a little logic sprinkled on
|
|
||||||
top, to act on network packets entering an interface, timeouts expiring,
|
|
||||||
mouse clicks, or other types of events. Such applications are often
|
|
||||||
very well suited to use an event loop.
|
|
||||||
|
|
||||||
Applications that need to churn massively parallel algorithms are more
|
|
||||||
suitable for running multiple (independent) threads on several CPU
|
|
||||||
cores. However, threaded applications must deal with the side effects
|
|
||||||
of concurrency, like race conditions, deadlocks, live locks, etc.
|
|
||||||
Writing error free threaded applications is hard, debugging them can be
|
|
||||||
even harder.
|
|
||||||
|
|
||||||
Sometimes the combination of multiple threads *and* an event loop per
|
|
||||||
thread can be the best approach, but each application of course needs to
|
|
||||||
be broken down individually to find the most optimal approach. Do keep
|
|
||||||
in mind, however, that not all systems your application will run on have
|
|
||||||
multiple CPU cores -- some small embedded systems still use a single CPU
|
|
||||||
core, even though they run Linux, with multiple threads a program may
|
|
||||||
actually run slower! Always profile your program, and if possible, test
|
|
||||||
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.
|
||||||
[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 however, a certain
|
||||||
of care is needed when dealing with APIs that employ signalfd. For
|
amount of care is needed when dealing with APIs that employ signalfd.
|
||||||
details, see [this article][4] at [lwn.net](http://lwn.net).
|
For details, see [this article][4] at [lwn.net](http://lwn.net).
|
||||||
|
|
||||||
> “Event driven software improves concurrency” -- [Dave Zarzycki, Apple][]
|
> “Event driven software improves concurrency” -- [Dave Zarzycki, Apple][]
|
||||||
|
|
||||||
@@ -66,17 +35,25 @@ details, see [this article][4] at [lwn.net](http://lwn.net).
|
|||||||
API
|
API
|
||||||
---
|
---
|
||||||
|
|
||||||
The C interface to [libuEv][] is listed in `uev.h`. It handles three
|
The C API to [libuEv][], listed in `uev/uev.h`, handles three different
|
||||||
different types of events: I/O (files, sockets, message queues, etc.),
|
types of events: I/O (files, sockets, message queues, etc.), timers, and
|
||||||
timers, and signals. With a slight caveat on signals detailed below
|
signals. The [Summary](#summary) details a slight caveat on signals.
|
||||||
in the [Summary](#summary).
|
|
||||||
|
Timers can be either relative, timeout in milliseconds, or absolute with
|
||||||
|
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
|
||||||
|
the wall clock changes, either via NTP or user input.
|
||||||
|
|
||||||
|
**NOTE:** On some systems, embedded systems in particular, `time_t` is a
|
||||||
|
32-bit integer that wraps around in the year 2038. [libuEv][] cannot
|
||||||
|
protect you against this problem, unfortunately.
|
||||||
|
|
||||||
```C
|
```C
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Callback example, arg is passed from watcher's *_init()
|
* Callback example, arg comes from the watcher's *_init() function,
|
||||||
* w->fd holds the file descriptor, events is set by libuEv
|
* w->fd holds the file descriptor or socket, and events is set by
|
||||||
* to indicate if any of UEV_READ and/or UEV_WRITE is ready.
|
* libuEv to indicate status: UEV_HUP, UEV_READ and/or UEV_WRITE
|
||||||
*/
|
*/
|
||||||
void callback (uev_t *w, void *arg, int events);
|
void callback (uev_t *w, void *arg, int events);
|
||||||
|
|
||||||
@@ -91,12 +68,18 @@ in the [Summary](#summary).
|
|||||||
int uev_io_start (uev_t *w);
|
int uev_io_start (uev_t *w);
|
||||||
int uev_io_stop (uev_t *w);
|
int uev_io_stop (uev_t *w);
|
||||||
|
|
||||||
/* Timer watcher: timeout and period in milliseconds */
|
/* Timer watcher: schedule a relative timer, timeout and period in milliseconds */
|
||||||
int uev_timer_init (uev_ctx_t *ctx, uev_t *w, uev_cb_t *cb, void *arg, int timeout, int period);
|
int uev_timer_init (uev_ctx_t *ctx, uev_t *w, uev_cb_t *cb, void *arg, int timeout, int period);
|
||||||
int uev_timer_set (uev_t *w, int timeout, int period); /* Change timeout or period */
|
int uev_timer_set (uev_t *w, int timeout, int period); /* Change timeout or period */
|
||||||
int uev_timer_start (uev_t *w); /* Restart a stopped timer */
|
int uev_timer_start (uev_t *w); /* Restart a stopped timer */
|
||||||
int uev_timer_stop (uev_t *w); /* Stop a timer */
|
int uev_timer_stop (uev_t *w); /* Stop a timer */
|
||||||
|
|
||||||
|
/* Cron watcher: schedule an absolute timer, when and period in time_t seconds */
|
||||||
|
int uev_cron_init (uev_ctx_t *ctx, uev_t *w, uev_cb_t *cb, void *arg, time_t when, time_t period);
|
||||||
|
int uev_cron_set (uev_t *w, int when, time_t period); /* Change when or period */
|
||||||
|
int uev_cron_start (uev_t *w); /* Restart a stopped cron */
|
||||||
|
int uev_cron_stop (uev_t *w); /* Stop a cron */
|
||||||
|
|
||||||
/* Signal watcher: signo is the signal to wait for, e.g., SIGTERM */
|
/* Signal watcher: signo is the signal to wait for, e.g., SIGTERM */
|
||||||
int uev_signal_init (uev_ctx_t *ctx, uev_t *w, uev_cb_t *cb, void *arg, int signo);
|
int uev_signal_init (uev_ctx_t *ctx, uev_t *w, uev_cb_t *cb, void *arg, int signo);
|
||||||
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 */
|
||||||
@@ -216,6 +199,16 @@ The output from the `pkg-config` tool holds no surprises:
|
|||||||
The prefix path `/usr/local/` shown here is only the default. Use the
|
The prefix path `/usr/local/` shown here is only the default. Use the
|
||||||
`configure` script to select a different prefix when installing libuEv.
|
`configure` script to select a different prefix when installing libuEv.
|
||||||
|
|
||||||
|
For GNU autotools based projects, use the following in `configure.ac`:
|
||||||
|
|
||||||
|
# Check for required libraries
|
||||||
|
PKG_CHECK_MODULES([uev], [libuev >= 1.4.0])
|
||||||
|
|
||||||
|
and in your `Makefile.am`:
|
||||||
|
|
||||||
|
proggy_CFLAGS = $(uev_CFLAGS)
|
||||||
|
proggy_LDADD = $(uev_LIBS)
|
||||||
|
|
||||||
|
|
||||||
Joystick Example
|
Joystick Example
|
||||||
----------------
|
----------------
|
||||||
@@ -296,19 +289,52 @@ Build & Install
|
|||||||
---------------
|
---------------
|
||||||
|
|
||||||
The library is built for and developed on GNU/Linux systems, patches to
|
The library is built for and developed on GNU/Linux systems, patches to
|
||||||
support *BSD and its kqueue interface are most welcome.
|
support *BSD and its [kqueue][] interface are most welcome.
|
||||||
|
|
||||||
libuEv use the GNU configure and build system. To try out the bundled
|
libuEv use the GNU configure and build system. To try out the bundled
|
||||||
examples, use the `--enable-examples` switch to the `configure` script.
|
examples, use the `--enable-examples` switch to the `configure` script.
|
||||||
|
|
||||||
./configure
|
./configure
|
||||||
make all
|
make -j5
|
||||||
make test
|
make test
|
||||||
make install
|
sudo make install-strip
|
||||||
|
sudo ldconfig
|
||||||
|
|
||||||
The resulting .so file is ~14 kiB (<kbd>make install-strip</kbd>).
|
The resulting .so file is ~14 kiB (<kbd>make install-strip</kbd>).
|
||||||
|
|
||||||
|
|
||||||
|
Background
|
||||||
|
----------
|
||||||
|
|
||||||
|
> “Why an event loop, why not use threads?”
|
||||||
|
|
||||||
|
With the advent of light-weight processes (threads) programmers these
|
||||||
|
days have a [golden hammer](http://c2.com/cgi/wiki?GoldenHammer) they
|
||||||
|
often swing without consideration. Event loops and non-blocking I/O is
|
||||||
|
often a far easier approach, as well as less error prone.
|
||||||
|
|
||||||
|
The purpose of many applications is, with a little logic sprinkled on
|
||||||
|
top, to act on network packets entering an interface, timeouts expiring,
|
||||||
|
mouse clicks, or other types of events. Such applications are often
|
||||||
|
very well suited to use an event loop.
|
||||||
|
|
||||||
|
Applications that need to churn massively parallel algorithms are more
|
||||||
|
suitable for running multiple (independent) threads on several CPU
|
||||||
|
cores. However, threaded applications must deal with the side effects
|
||||||
|
of concurrency, like race conditions, deadlocks, live locks, etc.
|
||||||
|
Writing error free threaded applications is hard, debugging them can be
|
||||||
|
even harder.
|
||||||
|
|
||||||
|
Sometimes the combination of multiple threads *and* an event loop per
|
||||||
|
thread can be the best approach, but each application of course needs to
|
||||||
|
be broken down individually to find the most optimal approach. Do keep
|
||||||
|
in mind, however, that not all systems your application will run on have
|
||||||
|
multiple CPU cores -- some small embedded systems still use a single CPU
|
||||||
|
core, even though they run Linux, with multiple threads a program may
|
||||||
|
actually run slower! Always profile your program, and if possible, test
|
||||||
|
it on different architectures.
|
||||||
|
|
||||||
|
|
||||||
Origin & References
|
Origin & References
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
@@ -334,6 +360,7 @@ event library used for inspiration is the very small [Picoev][9] by
|
|||||||
[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
|
||||||
|
[kqueue]: https://github.com/mheily/libkqueue
|
||||||
[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
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
LibuEv TODO
|
LibuEv TODO
|
||||||
===========
|
===========
|
||||||
|
|
||||||
* Make port to *BSD kqueue API, http://en.wikipedia.org/wiki/Kqueue
|
* Port to *BSD kqueue API, http://en.wikipedia.org/wiki/Kqueue
|
||||||
|
Also in UNIX Network Progamming, by W. Richard Stevens 3rd ed.
|
||||||
|
* Restore Lua bindings now that libuEv itself has stabilized
|
||||||
|
|
||||||
@@ -140,7 +140,8 @@ static struct timeval *run_once(uev_ctx_t *ctx)
|
|||||||
|
|
||||||
gettimeofday(&te, NULL);
|
gettimeofday(&te, NULL);
|
||||||
|
|
||||||
// if (xcount != count) fprintf(stderr, "Xcount: %d, Rcount: %d\n", xcount, count);
|
if (xcount != count)
|
||||||
|
fprintf(stderr, "Xcount: %d, Rcount: %d\n", xcount, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
timersub(&te, &ta, &ta);
|
timersub(&te, &ta, &ta);
|
||||||
@@ -229,7 +230,6 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Local Variables:
|
* Local Variables:
|
||||||
* version-control: t
|
|
||||||
* indent-tabs-mode: t
|
* indent-tabs-mode: t
|
||||||
* c-file-style: "linux"
|
* c-file-style: "linux"
|
||||||
* End:
|
* End:
|
||||||
|
|||||||
+2
-12
@@ -1,24 +1,14 @@
|
|||||||
# Use v2.61 for backwards compat with Ubuntu 12.04 LTS
|
AC_INIT(libuev, 1.5.2, https://github.com/troglobit/libuev/issues)
|
||||||
AC_PREREQ([2.61])
|
|
||||||
AC_INIT(libuEv, 1.4.0, https://github.com/troglobit/libuev/issues, libuev)
|
|
||||||
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])
|
||||||
|
|
||||||
AC_CONFIG_SRCDIR(uev.c)
|
AC_CONFIG_SRCDIR(uev.c)
|
||||||
AM_CONFIG_HEADER(config.h)
|
AM_CONFIG_HEADER(config.h)
|
||||||
AC_CONFIG_FILES([Makefile libuev.pc examples/Makefile])
|
AC_CONFIG_FILES([Makefile libuev.pc examples/Makefile tests/Makefile])
|
||||||
AC_CONFIG_MACRO_DIR([m4])
|
AC_CONFIG_MACRO_DIR([m4])
|
||||||
|
|
||||||
AC_PROG_CC
|
AC_PROG_CC
|
||||||
AM_PROG_AR
|
AM_PROG_AR
|
||||||
LT_INIT
|
LT_INIT
|
||||||
|
|
||||||
AC_ARG_ENABLE([examples],
|
|
||||||
[AS_HELP_STRING([--enable-examples], [build examples])],
|
|
||||||
[enable_examples=yes], [])
|
|
||||||
AM_CONDITIONAL([ENABLE_EXAMPLES], [test "$enable_examples" = yes])
|
|
||||||
|
|
||||||
AC_HEADER_STDC
|
|
||||||
AC_C_CONST
|
|
||||||
|
|
||||||
AC_OUTPUT
|
AC_OUTPUT
|
||||||
@@ -0,0 +1,165 @@
|
|||||||
|
/* libuEv - Micro event loop library
|
||||||
|
*
|
||||||
|
* Copyright (c) 2012 Flemming Madsen <flemming!madsen()madsensoft!dk>
|
||||||
|
* Copyright (c) 2013-2016 Joachim Nilsson <troglobit()gmail!com>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h> /* memset() */
|
||||||
|
#include <sys/timerfd.h>
|
||||||
|
#include <unistd.h> /* close(), read() */
|
||||||
|
|
||||||
|
#include "uev.h"
|
||||||
|
|
||||||
|
/* Missing defines in GLIBC <= 2.24 */
|
||||||
|
#ifndef TFD_TIMER_CANCEL_ON_SET
|
||||||
|
#define TFD_TIMER_CANCEL_ON_SET (1 << 1)
|
||||||
|
#endif
|
||||||
|
#ifndef TFD_SETTIME_FLAGS
|
||||||
|
#define TFD_SETTIME_FLAGS (TFD_TIMER_ABSTIME | TFD_TIMER_CANCEL_ON_SET)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create and start an at/cron job watcher
|
||||||
|
* @param ctx A valid libuEv context
|
||||||
|
* @param w Pointer to an uev_t watcher
|
||||||
|
* @param cb Callback function for cron job
|
||||||
|
* @param arg Optional callback argument
|
||||||
|
* @param when First point in time to call @param cb
|
||||||
|
* @param interval For an at job this is zero, for cron the offset interval
|
||||||
|
*
|
||||||
|
* For at jobs set @param interval to zero and only use @param when. For
|
||||||
|
* cron jobs, set @param interval to the offset. E.g., if the job should
|
||||||
|
* run every five minutes set the @param tm_min of struct tm to five.
|
||||||
|
*
|
||||||
|
* Use mktime() to create the time_t arguments. The special value zero
|
||||||
|
* may be used for @param when to denote 'now', where 'now' is when the
|
||||||
|
* event loop is started. You can also treat time_t simply as a signed
|
||||||
|
* integer. E.g., set @param interval to 3600 to create a cron job that
|
||||||
|
* runs every hour.
|
||||||
|
*
|
||||||
|
* @return POSIX OK(0) or non-zero with @param errno set on error.
|
||||||
|
*/
|
||||||
|
int uev_cron_init(uev_ctx_t *ctx, uev_t *w, uev_cb_t *cb, void *arg, time_t when, time_t interval)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
if (when < 0 || interval < 0) {
|
||||||
|
errno = ERANGE;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fd = timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK | TFD_CLOEXEC);
|
||||||
|
if (fd < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (uev_watcher_init(ctx, w, UEV_CRON_TYPE, cb, arg, fd, UEV_READ))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
if (uev_cron_set(w, when, interval)) {
|
||||||
|
uev_watcher_stop(w);
|
||||||
|
exit:
|
||||||
|
close(fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset an at/cron job watcher
|
||||||
|
* @param w Watcher to reset
|
||||||
|
* @param when First point in time to call @param cb
|
||||||
|
* @param interval For an at job this is zero, for cron the offset interval
|
||||||
|
*
|
||||||
|
* @return POSIX OK(0) or non-zero with @param errno set on error.
|
||||||
|
*/
|
||||||
|
int uev_cron_set(uev_t *w, time_t when, time_t interval)
|
||||||
|
{
|
||||||
|
/* Every watcher must be registered to a context */
|
||||||
|
if (!w || !w->ctx) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (when < 0 || interval < 0) {
|
||||||
|
errno = ERANGE;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Handle stopped timers */
|
||||||
|
if (w->fd < 0) {
|
||||||
|
/* Timer already stopped */
|
||||||
|
if (!when && !interval)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Remove from internal list */
|
||||||
|
LIST_REMOVE(w, link);
|
||||||
|
|
||||||
|
if (uev_cron_init(w->ctx, w, (uev_cb_t *)w->cb, w->arg, when, interval))
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
w->u.c.when = when;
|
||||||
|
w->u.c.interval = interval;
|
||||||
|
|
||||||
|
if (w->ctx->running) {
|
||||||
|
struct itimerspec time;
|
||||||
|
|
||||||
|
memset(&time, 0, sizeof(time));
|
||||||
|
time.it_value.tv_sec = when;
|
||||||
|
time.it_interval.tv_sec = interval;
|
||||||
|
if (timerfd_settime(w->fd, TFD_SETTIME_FLAGS, &time, NULL) < 0)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return uev_watcher_start(w);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start a stopped at/cron job watcher
|
||||||
|
* @param w Watcher to start (again)
|
||||||
|
*
|
||||||
|
* @return POSIX OK(0) or non-zero with @param errno set on error.
|
||||||
|
*/
|
||||||
|
int uev_cron_start(uev_t *w)
|
||||||
|
{
|
||||||
|
return uev_timer_start(w);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stop and unregister an at/cron job watcher
|
||||||
|
* @param w Watcher to stop
|
||||||
|
*
|
||||||
|
* @return POSIX OK(0) or non-zero with @param errno set on error.
|
||||||
|
*/
|
||||||
|
int uev_cron_stop(uev_t *w)
|
||||||
|
{
|
||||||
|
return uev_timer_stop(w);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Local Variables:
|
||||||
|
* indent-tabs-mode: t
|
||||||
|
* c-file-style: "linux"
|
||||||
|
* End:
|
||||||
|
*/
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
joystick
|
||||||
|
signal
|
||||||
|
cronrun
|
||||||
|
test
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
noinst_PROGRAMS = signal test joystick
|
noinst_PROGRAMS = joystick
|
||||||
AM_CPPFLAGS = -I$(top_srcdir)
|
AM_CPPFLAGS = -I$(top_srcdir)
|
||||||
AM_LDFLAGS = -L$(top_srcdir)
|
AM_LDFLAGS = -L$(top_srcdir)
|
||||||
LIBS = $(LTLIBINTL)
|
LIBS = $(LTLIBINTL)
|
||||||
|
|||||||
@@ -74,7 +74,6 @@ int main(void)
|
|||||||
/**
|
/**
|
||||||
* Local Variables:
|
* Local Variables:
|
||||||
* compile-command: "make joystick"
|
* compile-command: "make joystick"
|
||||||
* version-control: t
|
|
||||||
* indent-tabs-mode: t
|
* indent-tabs-mode: t
|
||||||
* c-file-style: "linux"
|
* c-file-style: "linux"
|
||||||
* End:
|
* End:
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/* libuEv - Micro event loop library
|
/* libuEv - Micro event loop library
|
||||||
*
|
*
|
||||||
* Copyright (c) 2012 Flemming Madsen <flemming!madsen()madsensoft!dk>
|
* Copyright (c) 2012 Flemming Madsen <flemming!madsen()madsensoft!dk>
|
||||||
* Copyright (c) 2013-2015 Joachim Nilsson <troglobit()gmail!com>
|
* Copyright (c) 2013-2016 Joachim Nilsson <troglobit()gmail!com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -23,7 +23,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#include "uev.h"
|
#include "uev.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -91,7 +90,6 @@ int uev_io_stop(uev_t *w)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Local Variables:
|
* Local Variables:
|
||||||
* version-control: t
|
|
||||||
* indent-tabs-mode: t
|
* indent-tabs-mode: t
|
||||||
* c-file-style: "linux"
|
* c-file-style: "linux"
|
||||||
* End:
|
* End:
|
||||||
|
|||||||
@@ -31,13 +31,14 @@
|
|||||||
|
|
||||||
/* I/O, timer, or signal watcher */
|
/* I/O, timer, or signal watcher */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
UEV_IO_TYPE = 1,
|
UEV_CRON_TYPE = 1,
|
||||||
UEV_TIMER_TYPE,
|
UEV_IO_TYPE,
|
||||||
UEV_SIGNAL_TYPE,
|
UEV_SIGNAL_TYPE,
|
||||||
|
UEV_TIMER_TYPE,
|
||||||
} 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)
|
#define UEV_EVENT_MASK (UEV_READ | UEV_WRITE | UEV_PRI | UEV_HUP)
|
||||||
|
|
||||||
/* Main libuEv context type */
|
/* Main libuEv context type */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -61,28 +62,36 @@ struct uev;
|
|||||||
void (*cb)(struct uev *, void *, int); \
|
void (*cb)(struct uev *, void *, int); \
|
||||||
void *arg; \
|
void *arg; \
|
||||||
\
|
\
|
||||||
/* Timer watchers, time in milliseconds */ \
|
/* Arguments for different watchers */ \
|
||||||
int timeout; \
|
union { \
|
||||||
int period; \
|
/* Cron watchers */ \
|
||||||
|
struct { \
|
||||||
|
time_t when; \
|
||||||
|
time_t interval; \
|
||||||
|
} c; \
|
||||||
\
|
\
|
||||||
/* Signal watchers */ \
|
/* Timer watchers, time in milliseconds */ \
|
||||||
int signo; \
|
struct { \
|
||||||
|
int timeout; \
|
||||||
|
int period; \
|
||||||
|
} t; \
|
||||||
|
} u; \
|
||||||
\
|
\
|
||||||
/* Watcher type */ \
|
/* Watcher type */ \
|
||||||
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);
|
||||||
|
|
||||||
#endif /* LIBUEV_PRIVATE_H_ */
|
#endif /* LIBUEV_PRIVATE_H_ */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Local Variables:
|
* Local Variables:
|
||||||
* version-control: t
|
|
||||||
* indent-tabs-mode: t
|
* indent-tabs-mode: t
|
||||||
* c-file-style: "linux"
|
* c-file-style: "linux"
|
||||||
* End:
|
* End:
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/* libuEv - Micro event loop library
|
/* libuEv - Micro event loop library
|
||||||
*
|
*
|
||||||
* Copyright (c) 2012 Flemming Madsen <flemming!madsen()madsensoft!dk>
|
* Copyright (c) 2012 Flemming Madsen <flemming!madsen()madsensoft!dk>
|
||||||
* Copyright (c) 2013-2015 Joachim Nilsson <troglobit()gmail!com>
|
* Copyright (c) 2013-2016 Joachim Nilsson <troglobit()gmail!com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -52,7 +52,7 @@ int uev_signal_init(uev_ctx_t *ctx, uev_t *w, uev_cb_t *cb, void *arg, int signo
|
|||||||
w->fd = -1;
|
w->fd = -1;
|
||||||
|
|
||||||
sigemptyset(&mask);
|
sigemptyset(&mask);
|
||||||
fd = signalfd(-1, &mask, SFD_NONBLOCK);
|
fd = signalfd(-1, &mask, SFD_NONBLOCK | SFD_CLOEXEC);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@@ -151,7 +151,6 @@ int uev_signal_stop(uev_t *w)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Local Variables:
|
* Local Variables:
|
||||||
* version-control: t
|
|
||||||
* indent-tabs-mode: t
|
* indent-tabs-mode: t
|
||||||
* c-file-style: "linux"
|
* c-file-style: "linux"
|
||||||
* End:
|
* End:
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
*.trs
|
||||||
|
*.log
|
||||||
|
active
|
||||||
|
complete
|
||||||
|
cronrun
|
||||||
|
signal
|
||||||
|
timer
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
EXTRA_DIST = check.h
|
||||||
|
CLEANFILES = *~ *.trs *.log
|
||||||
|
|
||||||
|
TESTS =
|
||||||
|
TESTS += active
|
||||||
|
TESTS += complete
|
||||||
|
TESTS += cronrun
|
||||||
|
TESTS += signal
|
||||||
|
TESTS += timer
|
||||||
|
|
||||||
|
check_PROGRAMS = $(TESTS)
|
||||||
|
|
||||||
|
# Ignore warnings about unused result, in e.g. write()
|
||||||
|
CFLAGS = -W -Wall -Wextra -Wno-unused-result
|
||||||
|
CPPFLAGS = -D_GNU_SOURCE
|
||||||
|
LDADD = -L../ ../libuev.la
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
#include "check.h"
|
||||||
|
#include <time.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
#define TIMEOUT1 2 /* 2 sec */
|
||||||
|
#define TIMEOUT2 4 /* 4 sec */
|
||||||
|
#define DAYLY (24 * 60 * 60) /* Seconds in one day */
|
||||||
|
|
||||||
|
uev_t timer1;
|
||||||
|
uev_t timer2;
|
||||||
|
uev_t timer3;
|
||||||
|
uev_t cron1;
|
||||||
|
uev_t cron2;
|
||||||
|
|
||||||
|
static void cb(uev_t *w, void *UNUSED(arg), int UNUSED(events))
|
||||||
|
{
|
||||||
|
fail_unless(w == &timer1);
|
||||||
|
|
||||||
|
fail_unless(uev_timer_active(&timer2));
|
||||||
|
fail_unless(!uev_timer_active(&timer3));
|
||||||
|
fail_unless(uev_cron_active(&cron1));
|
||||||
|
fail_unless(uev_cron_active(&cron2));
|
||||||
|
|
||||||
|
uev_timer_stop(&timer2);
|
||||||
|
uev_timer_stop(&cron2);
|
||||||
|
|
||||||
|
fail_unless(!uev_timer_active(&timer2));
|
||||||
|
fail_unless(!uev_cron_active(&cron2));
|
||||||
|
|
||||||
|
uev_exit(w->ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
uev_ctx_t ctx;
|
||||||
|
struct timeval tomorrow;
|
||||||
|
|
||||||
|
gettimeofday(&tomorrow, NULL);
|
||||||
|
tomorrow.tv_sec += 24 * 60 * 60;
|
||||||
|
|
||||||
|
uev_init(&ctx);
|
||||||
|
uev_timer_init(&ctx, &timer1, cb, NULL, TIMEOUT1 * 1000, 0);
|
||||||
|
uev_timer_init(&ctx, &timer2, cb, NULL, TIMEOUT2 * 1000, 0);
|
||||||
|
uev_timer_init(&ctx, &timer3, cb, NULL, TIMEOUT2 * 1000, 0);
|
||||||
|
uev_timer_stop(&timer3);
|
||||||
|
|
||||||
|
uev_cron_init(&ctx, &cron1, cb, NULL, tomorrow.tv_sec, 24 * 60 * 60);
|
||||||
|
uev_cron_init(&ctx, &cron2, cb, NULL, tomorrow.tv_sec, 24 * 60 * 60);
|
||||||
|
|
||||||
|
return uev_run(&ctx, 0);
|
||||||
|
}
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
#ifndef UEV_TESTS_CHECK_H_
|
||||||
|
#define UEV_TESTS_CHECK_H_
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "../uev.h"
|
||||||
|
|
||||||
|
#define UNUSED(arg) arg __attribute__ ((unused))
|
||||||
|
|
||||||
|
#define fail_unless(test) \
|
||||||
|
do { \
|
||||||
|
if (!(test)) { \
|
||||||
|
fprintf(stderr, \
|
||||||
|
"----------------------------------------------\n" \
|
||||||
|
"%s:%d: test FAILED:\nFailed test: %s\n" \
|
||||||
|
"----------------------------------------------\n", \
|
||||||
|
__FILE__, __LINE__, #test); \
|
||||||
|
exit(1); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
static inline int test(int result, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
char buf[80];
|
||||||
|
size_t len;
|
||||||
|
va_list ap;
|
||||||
|
const char success[] = " \033[1m[ OK ]\033[0m\n";
|
||||||
|
const char failure[] = " \033[7m[FAIL]\033[0m\n";
|
||||||
|
const char dots[] = " .....................................................................";
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
len = vsnprintf(buf, sizeof(buf), fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
write(STDERR_FILENO, buf, len);
|
||||||
|
write(STDERR_FILENO, dots, 60 - len); /* pad with dots. */
|
||||||
|
|
||||||
|
if (!result)
|
||||||
|
write(STDERR_FILENO, success, strlen(success));
|
||||||
|
else
|
||||||
|
write(STDERR_FILENO, failure, strlen(failure));
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int timespec_newer(const struct timespec *a, const struct timespec *b)
|
||||||
|
{
|
||||||
|
if (a->tv_sec != b->tv_sec)
|
||||||
|
return a->tv_sec > b->tv_sec;
|
||||||
|
|
||||||
|
return a->tv_nsec > b->tv_nsec;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline char *timespec2str(struct timespec *ts, char *buf, size_t len)
|
||||||
|
{
|
||||||
|
size_t ret, pos;
|
||||||
|
struct tm t;
|
||||||
|
|
||||||
|
memset(buf, 0, len);
|
||||||
|
|
||||||
|
tzset();
|
||||||
|
if (localtime_r(&(ts->tv_sec), &t) == NULL)
|
||||||
|
return buf;
|
||||||
|
|
||||||
|
ret = strftime(buf, len, "%F %T", &t);
|
||||||
|
if (ret == 0)
|
||||||
|
return buf;
|
||||||
|
len -= ret - 1;
|
||||||
|
|
||||||
|
pos = strlen(buf);
|
||||||
|
len -= pos;
|
||||||
|
snprintf(&buf[pos], len, ".%09ld", ts->tv_nsec);
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* UEV_TESTS_CHECK_H_ */
|
||||||
@@ -22,14 +22,8 @@
|
|||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "check.h"
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <unistd.h> /* intptr_t */
|
|
||||||
|
|
||||||
#include "uev.h"
|
|
||||||
|
|
||||||
#define UNUSED(arg) arg __attribute__ ((unused))
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int counter;
|
int counter;
|
||||||
@@ -138,15 +132,13 @@ int main(void)
|
|||||||
uev_run(&ctx, 0);
|
uev_run(&ctx, 0);
|
||||||
|
|
||||||
fprintf(stderr, "Period is %d must be 10: %s\n", period, 10 == period ? "OK" : "ERROR!");
|
fprintf(stderr, "Period is %d must be 10: %s\n", period, 10 == period ? "OK" : "ERROR!");
|
||||||
if (10 != period)
|
fail_unless(10 == period);
|
||||||
return 1;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Local Variables:
|
* Local Variables:
|
||||||
* version-control: t
|
|
||||||
* indent-tabs-mode: t
|
* indent-tabs-mode: t
|
||||||
* c-file-style: "linux"
|
* c-file-style: "linux"
|
||||||
* End:
|
* End:
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
/* Test cron API in libuEv event library
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016 Joachim Nilsson <troglobit()gmail!com>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "check.h"
|
||||||
|
#include <time.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
#define TIMEOUT 2
|
||||||
|
#define INTERVAL 2
|
||||||
|
|
||||||
|
struct timeval tv;
|
||||||
|
|
||||||
|
static void cron_job(uev_t *w, void *UNUSED(arg), int UNUSED(events))
|
||||||
|
{
|
||||||
|
static int laps = 3;
|
||||||
|
struct timeval now;
|
||||||
|
|
||||||
|
/* Update timer every lap */
|
||||||
|
tv.tv_sec += TIMEOUT;
|
||||||
|
|
||||||
|
gettimeofday(&now, NULL);
|
||||||
|
printf("Cron job HELO %s", ctime(&now.tv_sec));
|
||||||
|
fail_unless(now.tv_sec == tv.tv_sec);
|
||||||
|
|
||||||
|
if (!laps--)
|
||||||
|
uev_exit(w->ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
uev_t cron_watcher;
|
||||||
|
uev_ctx_t ctx;
|
||||||
|
time_t when, interval;
|
||||||
|
|
||||||
|
uev_init(&ctx);
|
||||||
|
|
||||||
|
gettimeofday(&tv, NULL);
|
||||||
|
printf("Start of test %s", ctime(&tv.tv_sec));
|
||||||
|
printf("Expected cron %s", ctime(&when));
|
||||||
|
|
||||||
|
when = tv.tv_sec + TIMEOUT;
|
||||||
|
interval = INTERVAL;
|
||||||
|
uev_cron_init(&ctx, &cron_watcher, cron_job, NULL, when, interval);
|
||||||
|
|
||||||
|
return uev_run(&ctx, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Local Variables:
|
||||||
|
* indent-tabs-mode: t
|
||||||
|
* c-file-style: "linux"
|
||||||
|
* End:
|
||||||
|
*/
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define _GNU_SOURCE
|
#include "check.h"
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <sched.h>
|
#include <sched.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
@@ -33,8 +33,6 @@
|
|||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "uev.h"
|
|
||||||
|
|
||||||
#define UNUSED(arg) arg __attribute__ ((unused))
|
#define UNUSED(arg) arg __attribute__ ((unused))
|
||||||
#define DO_SEGFAULT 1
|
#define DO_SEGFAULT 1
|
||||||
|
|
||||||
@@ -134,7 +132,6 @@ int main(void)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Local Variables:
|
* Local Variables:
|
||||||
* version-control: t
|
|
||||||
* indent-tabs-mode: t
|
* indent-tabs-mode: t
|
||||||
* c-file-style: "linux"
|
* c-file-style: "linux"
|
||||||
* End:
|
* End:
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
#include "check.h"
|
||||||
|
#include <time.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
#define TIMEOUT 2 /* 2 sec */
|
||||||
|
struct timeval start;
|
||||||
|
|
||||||
|
static void cb(uev_t *w, void *UNUSED(arg), int UNUSED(events))
|
||||||
|
{
|
||||||
|
struct timeval now;
|
||||||
|
|
||||||
|
gettimeofday(&now, NULL);
|
||||||
|
fail_unless(now.tv_sec == start.tv_sec + TIMEOUT);
|
||||||
|
|
||||||
|
uev_exit(w->ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
uev_t w;
|
||||||
|
uev_ctx_t ctx;
|
||||||
|
|
||||||
|
uev_init(&ctx);
|
||||||
|
uev_timer_init(&ctx, &w, cb, NULL, TIMEOUT * 1000, 0);
|
||||||
|
gettimeofday(&start, NULL);
|
||||||
|
|
||||||
|
return uev_run(&ctx, 0);
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
/* libuEv - Micro event loop library
|
/* libuEv - Micro event loop library
|
||||||
*
|
*
|
||||||
* Copyright (c) 2012 Flemming Madsen <flemming!madsen()madsensoft!dk>
|
* Copyright (c) 2012 Flemming Madsen <flemming!madsen()madsensoft!dk>
|
||||||
* Copyright (c) 2013-2015 Joachim Nilsson <troglobit()gmail!com>
|
* Copyright (c) 2013-2016 Joachim Nilsson <troglobit()gmail!com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -67,7 +67,12 @@ int uev_timer_init(uev_ctx_t *ctx, uev_t *w, uev_cb_t *cb, void *arg, int timeou
|
|||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK);
|
if (timeout < 0 || period < 0) {
|
||||||
|
errno = ERANGE;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@@ -100,6 +105,11 @@ int uev_timer_set(uev_t *w, int timeout, int period)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (timeout < 0 || period < 0) {
|
||||||
|
errno = ERANGE;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Handle stopped timers */
|
/* Handle stopped timers */
|
||||||
if (w->fd < 0) {
|
if (w->fd < 0) {
|
||||||
/* Timer already stopped */
|
/* Timer already stopped */
|
||||||
@@ -113,15 +123,16 @@ int uev_timer_set(uev_t *w, int timeout, int period)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
w->timeout = timeout;
|
w->u.t.timeout = timeout;
|
||||||
w->period = period;
|
w->u.t.period = period;
|
||||||
|
|
||||||
if (w->ctx->running) {
|
if (w->ctx->running) {
|
||||||
struct itimerspec time;
|
struct itimerspec time;
|
||||||
|
|
||||||
msec2tspec(timeout, &time.it_value);
|
msec2tspec(timeout, &time.it_value);
|
||||||
msec2tspec(period, &time.it_interval);
|
msec2tspec(period, &time.it_interval);
|
||||||
timerfd_settime(w->fd, 0, &time, NULL);
|
if (timerfd_settime(w->fd, 0, &time, NULL) < 0)
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return uev_watcher_start(w);
|
return uev_watcher_start(w);
|
||||||
@@ -143,7 +154,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->timeout, w->period);
|
return uev_timer_set(w, w->u.t.timeout, w->u.t.period);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -169,7 +180,6 @@ int uev_timer_stop(uev_t *w)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Local Variables:
|
* Local Variables:
|
||||||
* version-control: t
|
|
||||||
* indent-tabs-mode: t
|
* indent-tabs-mode: t
|
||||||
* c-file-style: "linux"
|
* c-file-style: "linux"
|
||||||
* End:
|
* End:
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/* libuEv - Micro event loop library
|
/* libuEv - Micro event loop library
|
||||||
*
|
*
|
||||||
* Copyright (c) 2012 Flemming Madsen <flemming!madsen()madsensoft!dk>
|
* Copyright (c) 2012 Flemming Madsen <flemming!madsen()madsensoft!dk>
|
||||||
* Copyright (c) 2013-2015 Joachim Nilsson <troglobit()gmail!com>
|
* Copyright (c) 2013-2016 Joachim Nilsson <troglobit()gmail!com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -36,8 +36,9 @@
|
|||||||
|
|
||||||
static int _init(uev_ctx_t *ctx, int close_old)
|
static int _init(uev_ctx_t *ctx, int close_old)
|
||||||
{
|
{
|
||||||
int fd = epoll_create1(EPOLL_CLOEXEC);
|
int fd;
|
||||||
|
|
||||||
|
fd = epoll_create1(EPOLL_CLOEXEC);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@@ -67,7 +68,7 @@ int uev_watcher_init(uev_ctx_t *ctx, uev_t *w, uev_type_t type, uev_cb_t *cb, vo
|
|||||||
w->type = type;
|
w->type = type;
|
||||||
w->active = 0;
|
w->active = 0;
|
||||||
w->fd = fd;
|
w->fd = fd;
|
||||||
w->cb = (void *)cb;
|
w->cb = cb;
|
||||||
w->arg = arg;
|
w->arg = arg;
|
||||||
w->events = events;
|
w->events = events;
|
||||||
|
|
||||||
@@ -123,6 +124,15 @@ int uev_watcher_stop(uev_t *w)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Private to libuEv, do not use directly! */
|
||||||
|
int uev_watcher_active(uev_t *w)
|
||||||
|
{
|
||||||
|
if (!w)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return w->active;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an event loop context
|
* Create an event loop context
|
||||||
* @param ctx Pointer to an uev_ctx_t context to be initialized
|
* @param ctx Pointer to an uev_ctx_t context to be initialized
|
||||||
@@ -165,6 +175,7 @@ int uev_exit(uev_ctx_t *ctx)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
switch (w->type) {
|
switch (w->type) {
|
||||||
|
case UEV_CRON_TYPE:
|
||||||
case UEV_TIMER_TYPE:
|
case UEV_TIMER_TYPE:
|
||||||
uev_timer_stop(w);
|
uev_timer_stop(w);
|
||||||
break;
|
break;
|
||||||
@@ -218,8 +229,10 @@ int uev_run(uev_ctx_t *ctx, int flags)
|
|||||||
|
|
||||||
/* Start all dormant timers */
|
/* Start all dormant timers */
|
||||||
LIST_FOREACH(w, &ctx->watchers, link) {
|
LIST_FOREACH(w, &ctx->watchers, link) {
|
||||||
|
if (UEV_CRON_TYPE == w->type)
|
||||||
|
uev_cron_set(w, w->u.c.when, w->u.c.interval);
|
||||||
if (UEV_TIMER_TYPE == w->type)
|
if (UEV_TIMER_TYPE == w->type)
|
||||||
uev_timer_set(w, w->timeout, w->period);
|
uev_timer_set(w, w->u.t.timeout, w->u.t.period);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (ctx->running) {
|
while (ctx->running) {
|
||||||
@@ -273,6 +286,24 @@ int uev_run(uev_ctx_t *ctx, int flags)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (UEV_CRON_TYPE == w->type) {
|
||||||
|
uint64_t exp;
|
||||||
|
|
||||||
|
if (read(w->fd, &exp, sizeof(exp)) != sizeof(exp)) {
|
||||||
|
if (errno != ECANCELED) {
|
||||||
|
uev_exit(ctx);
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
|
||||||
|
events[i].events = UEV_HUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!w->u.c.interval)
|
||||||
|
w->u.c.when = 0;
|
||||||
|
else
|
||||||
|
w->u.c.when += w->u.c.interval;
|
||||||
|
}
|
||||||
|
|
||||||
if (UEV_TIMER_TYPE == w->type) {
|
if (UEV_TIMER_TYPE == w->type) {
|
||||||
uint64_t exp;
|
uint64_t exp;
|
||||||
|
|
||||||
@@ -281,8 +312,8 @@ int uev_run(uev_ctx_t *ctx, int flags)
|
|||||||
return -3;
|
return -3;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!w->period)
|
if (!w->u.t.period)
|
||||||
w->timeout = 0;
|
w->u.t.timeout = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UEV_SIGNAL_TYPE == w->type) {
|
if (UEV_SIGNAL_TYPE == w->type) {
|
||||||
@@ -298,8 +329,12 @@ int uev_run(uev_ctx_t *ctx, int flags)
|
|||||||
if (w->cb)
|
if (w->cb)
|
||||||
w->cb(w, w->arg, events[i].events & UEV_EVENT_MASK);
|
w->cb(w, w->arg, events[i].events & UEV_EVENT_MASK);
|
||||||
|
|
||||||
|
if (UEV_CRON_TYPE == w->type) {
|
||||||
|
if (!w->u.c.when)
|
||||||
|
uev_timer_stop(w);
|
||||||
|
}
|
||||||
if (UEV_TIMER_TYPE == w->type) {
|
if (UEV_TIMER_TYPE == w->type) {
|
||||||
if (!w->timeout)
|
if (!w->u.t.timeout)
|
||||||
uev_timer_stop(w);
|
uev_timer_stop(w);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -311,10 +346,8 @@ int uev_run(uev_ctx_t *ctx, int flags)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Local Variables:
|
* Local Variables:
|
||||||
* version-control: t
|
|
||||||
* indent-tabs-mode: t
|
* indent-tabs-mode: t
|
||||||
* c-file-style: "linux"
|
* c-file-style: "linux"
|
||||||
* End:
|
* End:
|
||||||
|
|||||||
@@ -35,17 +35,25 @@
|
|||||||
#define UEV_READ EPOLLIN
|
#define UEV_READ EPOLLIN
|
||||||
#define UEV_WRITE EPOLLOUT
|
#define UEV_WRITE EPOLLOUT
|
||||||
#define UEV_PRI EPOLLPRI
|
#define UEV_PRI EPOLLPRI
|
||||||
|
#define UEV_HUP EPOLLHUP
|
||||||
|
|
||||||
/* Run flags */
|
/* Run flags */
|
||||||
#define UEV_ONCE 1
|
#define UEV_ONCE 1
|
||||||
#define UEV_NONBLOCK 2
|
#define UEV_NONBLOCK 2
|
||||||
|
|
||||||
|
/* Macros */
|
||||||
|
#define uev_io_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_signal_active(w) uev_watcher_active(w)
|
||||||
|
|
||||||
/* Event watcher */
|
/* Event watcher */
|
||||||
typedef struct uev {
|
typedef struct uev {
|
||||||
/* Private data for libuEv internal engine */
|
/* Private data for libuEv internal engine */
|
||||||
uev_private_t type;
|
uev_private_t type;
|
||||||
|
|
||||||
/* Public data for users to reference */
|
/* Public data for users to reference */
|
||||||
|
int signo;
|
||||||
int fd;
|
int fd;
|
||||||
uev_ctx_t *ctx;
|
uev_ctx_t *ctx;
|
||||||
} uev_t;
|
} uev_t;
|
||||||
@@ -68,6 +76,11 @@ int uev_timer_set (uev_t *w, int timeout, int period);
|
|||||||
int uev_timer_start (uev_t *w);
|
int uev_timer_start (uev_t *w);
|
||||||
int uev_timer_stop (uev_t *w);
|
int uev_timer_stop (uev_t *w);
|
||||||
|
|
||||||
|
int uev_cron_init (uev_ctx_t *ctx, uev_t *w, uev_cb_t *cb, void *arg, time_t when, time_t interval);
|
||||||
|
int uev_cron_set (uev_t *w, time_t when, time_t interval);
|
||||||
|
int uev_cron_start (uev_t *w);
|
||||||
|
int uev_cron_stop (uev_t *w);
|
||||||
|
|
||||||
int uev_signal_init (uev_ctx_t *ctx, uev_t *w, uev_cb_t *cb, void *arg, int signo);
|
int uev_signal_init (uev_ctx_t *ctx, uev_t *w, uev_cb_t *cb, void *arg, int signo);
|
||||||
int uev_signal_set (uev_t *w, int signo);
|
int uev_signal_set (uev_t *w, int signo);
|
||||||
int uev_signal_start (uev_t *w);
|
int uev_signal_start (uev_t *w);
|
||||||
@@ -77,7 +90,6 @@ int uev_signal_stop (uev_t *w);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Local Variables:
|
* Local Variables:
|
||||||
* version-control: t
|
|
||||||
* indent-tabs-mode: t
|
* indent-tabs-mode: t
|
||||||
* c-file-style: "linux"
|
* c-file-style: "linux"
|
||||||
* End:
|
* End:
|
||||||
|
|||||||
Reference in new issue
Block a user