Orion Poplawski | 22 Apr 23:31 2015

passenger's modification to libeio

phusion passenger 5.0.6 ships a modified libeio 4.15.  Fedora builds it
against system libeio, so this fails due to missing symbols.  The full diff is:

diff -ru ../libev/libev-4.15/ev.c passenger-5.0.6/ext/libev/ev.c
--- ../libev/libev-4.15/ev.c    2013-03-01 04:10:48.000000000 -0700
+++ passenger-5.0.6/ext/libev/ev.c      2013-10-26 16:00:00.000000000 -0600
 <at>  <at>  -967,7 +967,7  <at>  <at> 
   #define ecb_unreachable() __builtin_unreachable ()
   /* this seems to work fine, but gcc always emits a warning for it :/ */
-  ecb_inline void ecb_unreachable (void) ecb_noreturn;
+  ecb_inline ecb_noreturn void ecb_unreachable (void);
   ecb_inline void ecb_unreachable (void) { }

 <at>  <at>  -2477,6 +2477,18  <at>  <at> 
   return backend;

+ev_backend_fd (EV_P) EV_THROW
+  return backend_fd;
+ev_loop_get_pipe (EV_P_ unsigned int index) EV_THROW
+  return evpipe[index];
(Continue reading)

Thilo Schulz | 17 Apr 19:48 2015

Suggestion for new watcher type: called immediately after execution of current watcher has finished


the software I am currently writing is very modular - with functions in
modules being called directly from the event library, and with modules
having control over when they can be unloaded (this may happen when
a final closing event arrives, and the module then knows it's done and can
I can't simply make the module itself unload from the same call as
the event watcher, because this would of course ruin the callstack.
What I was missing for this case was a way to make libev execute something
immediately after the current watcher is done, even before other pending
watchers are executed.
Instead, I used a prepare watcher, which is close enough for me. (In my
case it doesn't really matter if pending watchers are executed first).

The prepare watcher has its own traps, as I laid out in my prior email.


Best regards,
Thilo Schulz

libev mailing list
libev <at> lists.schmorp.de
Thilo Schulz | 17 Apr 19:46 2015

ev_prepare watcher awkwardness

Dear list, dear Mr. Lehmann, 

first I would like to thank you for this excellent piece of software.
I've been using it for quite some time.
In developing software using this event library, I've noticed a
few "nice to haves" that I'm going to lay out in this email and a next email
to this list.

It so happens in my software there is a a prepare watcher which may,
somewhere in the call tree, add another prepare watcher, that shall execute
before the process blocks for new events.
If memory serves correctly looking at libev code, as this new prepare watcher
has not been properly "collected" yet, it will only be executed _after_ the
upcoming select()/poll(). While this collect behaviour is sensible for
file descriptors, in the case of ev_prepare() watchers this is somewhat

I am currently working around this by always
also installing an idle watcher to make sure the program doesn't block for at
least one event loop iteration. But like I said, this solution is rather awkward.

I can have a look at it and try to write a patch if you're interested. Thought
I'd ask first.


Best regards,
Thilo Schulz

libev mailing list
(Continue reading)

Chris Zahka | 10 Apr 23:20 2015

ev_timer_start() appears to not wake up loop from epoll_wait()


I hope this message finds you well.

The following issue is likely self-inflicted but it is not clear how at this point.

The attached test code is a program that runs with two threads (the main thread and a child pthread).

The main thread:
1. Initializes the child event watchers (one async, one timer)
2. Calls pthread_create() which results in the ev_run() executing in the child thread
3. calls ev_timer_start() with a value of 0.5 seconds
4. sleeps for several seconds, to ensure that the child thread will get called

Note: I typically use pthread conditionals to ensure that an event on another thread gets executed.

The child thread:
1. After the ev_timer_start() is called it *should* wake up 0.5 seconds later, printing out a message showing that the callback has occurred

What I see happening, instead of waking up 0.5 seconds later, is it takes roughly 60 seconds for the timer to start going off. I put some debug in the ev.c code and determined that within the ev_run() function, the waittime getting passed to backend_poll was 59.793 seconds.

It appears as though ev_timer_start() does not cause the backend_poll to wake up. Is this the expected behavior or am I doing something wrong?

I have also attached the config.log file so you can see the architecture where I am having problems. Note that I also tried the same program on a x64 system with the same results.

Thanks very much for your time.


Chris Zahka
Attachment (config.log): application/octet-stream, 48 KiB
Attachment (libev_timer_test_plain.c): text/x-csrc, 4255 bytes
Attachment (Makefile): application/octet-stream, 441 bytes
libev mailing list
libev <at> lists.schmorp.de
Andrey Pokrovskiy | 6 Apr 22:42 2015

Is ev_async_send() a seq. cst. barrier?


Is it a correct assumption that ev_async_send() is a sequential
consistency barrier?

From source code it doesn't seem so.
ev_async_send() publishes event with
    w->sent = 1;
Where "sent" is a volatile sig_atomic_t which doesn't impose any
ordering (afaik).

    (1) last_event = event; // or __atomic_store_n(&last_event, event,
    (2) ev_async_send(ev_event);
I think it's possible that "w->sent = 1" in (2) can be moved (observed
by other threads) before (1).

Could anybody comment on this please?

libev mailing list
libev <at> lists.schmorp.de
Ri-Ping YU | 24 Mar 09:34 2015

How can I get demo for Libev

Hi, everyone
    We're trying to adopt "Libev" in our project, but I have not found any demo for it.
    I want to know how can I start with "Libev", and how can I design my program with it.

    Appreciate for any response!

libev mailing list
libev <at> lists.schmorp.de
Ri-Ping YU | 24 Mar 08:15 2015

Error while cross-compiling

Hi, everyone
    I'm trying to adopt Libev in my project. But one error occured while cross-compiling, Log is below


root <at> YRP-ES-QD:/opt/DevelopmentTraining/Subjects/Libev/libev-4.19# ./configure --host=arm-none-linux-gnueabi --prefix=/opt/TestCell/Temp 
checking for a BSD-compatible install... /usr/bin/install -c 
checking whether build environment is sane... yes 
checking for arm-none-linux-gnueabi-strip... arm-none-linux-gnueabi-strip 
checking for a thread-safe mkdir -p... /bin/mkdir -p 
checking for gawk... gawk 
checking whether make sets $(MAKE)... yes 
checking whether make supports nested variables... yes 
checking whether to enable maintainer-specific portions of Makefiles... no 
checking for arm-none-linux-gnueabi-gcc... arm-none-linux-gnueabi-gcc 
checking whether the C compiler works... yes 
checking for C compiler default output file name... a.out 
checking for suffix of executables... 
checking whether we are cross compiling... yes 
checking for suffix of object files... o 
checking whether we are using the GNU C compiler... yes 
checking whether arm-none-linux-gnueabi-gcc accepts -g... yes 
checking for arm-none-linux-gnueabi-gcc option to accept ISO C89... none needed 
checking whether arm-none-linux-gnueabi-gcc understands -c and -o together... yes 
checking for style of include used by make... GNU 
checking dependency style of arm-none-linux-gnueabi-gcc... gcc3 
checking build system type... i686-pc-linux-gnu 
checking host system type... arm-none-linux-gnueabi 
checking how to print strings... printf 
checking for a sed that does not truncate output... /bin/sed 
checking for grep that handles long lines and -e... /bin/grep 
checking for egrep... /bin/grep -E 
checking for fgrep... /bin/grep -F 
checking for ld used by arm-none-linux-gnueabi-gcc... /opt/DVRRDK/DVRRDK_03.00.00.00/ti_tools/cgt_a8/arm-2009q1/arm-none-linux-gnueabi/bin/ld 
checking if the linker (/opt/DVRRDK/DVRRDK_03.00.00.00/ti_tools/cgt_a8/arm-2009q1/arm-none-linux-gnueabi/bin/ld) is GNU ld... yes 
checking for BSD- or MS-compatible name lister (nm)... /opt/DVRRDK/DVRRDK_03.00.00.00/ti_tools/cgt_a8/arm-2009q1/bin/arm-none-linux-gnueabi-nm -B 
checking the name lister (/opt/DVRRDK/DVRRDK_03.00.00.00/ti_tools/cgt_a8/arm-2009q1/bin/arm-none-linux-gnueabi-nm -B) interface... BSD nm 
checking whether ln -s works... yes 
checking the maximum length of command line arguments... 1572864 
checking whether the shell understands some XSI constructs... yes 
checking whether the shell understands "+="... yes 
checking how to convert i686-pc-linux-gnu file names to arm-none-linux-gnueabi format... func_convert_file_noop 
checking how to convert i686-pc-linux-gnu file names to toolchain format... func_convert_file_noop 
checking for /opt/DVRRDK/DVRRDK_03.00.00.00/ti_tools/cgt_a8/arm-2009q1/arm-none-linux-gnueabi/bin/ld option to reload object files... -r 
checking for arm-none-linux-gnueabi-objdump... arm-none-linux-gnueabi-objdump 
checking how to recognize dependent libraries... pass_all 
checking for arm-none-linux-gnueabi-dlltool... no 
checking for dlltool... no 
checking how to associate runtime and link libraries... printf %s\n 
checking for arm-none-linux-gnueabi-ar... arm-none-linux-gnueabi-ar 
checking for archiver <at> FILE support... <at>  
checking for arm-none-linux-gnueabi-strip... (cached) arm-none-linux-gnueabi-strip 
checking for arm-none-linux-gnueabi-ranlib... arm-none-linux-gnueabi-ranlib 
checking command to parse /opt/DVRRDK/DVRRDK_03.00.00.00/ti_tools/cgt_a8/arm-2009q1/bin/arm-none-linux-gnueabi-nm -B output from arm-none-linux-gnueabi-gcc object... ok 
checking for sysroot... no 
checking for arm-none-linux-gnueabi-mt... no 
checking for mt... mt 
configure: WARNING: using cross tools not prefixed with host triplet 
checking if mt is a manifest tool... no 
checking how to run the C preprocessor... arm-none-linux-gnueabi-gcc -E 
checking for ANSI C header files... yes 
checking for sys/types.h... yes 
checking for sys/stat.h... yes 
checking for stdlib.h... yes 
checking for string.h... yes 
checking for memory.h... yes 
checking for strings.h... yes 
checking for inttypes.h... yes 
checking for stdint.h... yes 
checking for unistd.h... yes 
checking for dlfcn.h... yes 
checking for objdir... .libs 
checking if arm-none-linux-gnueabi-gcc supports -fno-rtti -fno-exceptions... no 
checking for arm-none-linux-gnueabi-gcc option to produce PIC... -fPIC -DPIC 
checking if arm-none-linux-gnueabi-gcc PIC flag -fPIC -DPIC works... yes 
checking if arm-none-linux-gnueabi-gcc static flag -static works... yes 
checking if arm-none-linux-gnueabi-gcc supports -c -o file.o... yes 
checking if arm-none-linux-gnueabi-gcc supports -c -o file.o... (cached) yes 
checking whether the arm-none-linux-gnueabi-gcc linker (/opt/DVRRDK/DVRRDK_03.00.00.00/ti_tools/cgt_a8/arm-2009q1/arm-none-linux-gnueabi/bin/ld) supports shared libraries... yes 
checking whether -lc should be explicitly linked in... no 
checking dynamic linker characteristics... GNU/Linux ld.so 
checking how to hardcode library paths into programs... immediate 
checking whether stripping libraries is possible... yes 
checking if libtool supports shared libraries... yes 
checking whether to build shared libraries... yes 
checking whether to build static libraries... yes 
checking sys/inotify.h usability... yes 
checking sys/inotify.h presence... yes 
checking for sys/inotify.h... yes 
checking sys/epoll.h usability... yes 
checking sys/epoll.h presence... yes 
checking for sys/epoll.h... yes 
checking sys/event.h usability... no 
checking sys/event.h presence... no 
checking for sys/event.h... no 
checking port.h usability... no 
checking port.h presence... no 
checking for port.h... no 
checking poll.h usability... yes 
checking poll.h presence... yes 
checking for poll.h... yes 
checking sys/select.h usability... yes 
checking sys/select.h presence... yes 
checking for sys/select.h... yes 
checking sys/eventfd.h usability... yes 
checking sys/eventfd.h presence... yes 
checking for sys/eventfd.h... yes 
checking sys/signalfd.h usability... yes 
checking sys/signalfd.h presence... yes 
checking for sys/signalfd.h... yes 
checking for inotify_init... yes 
checking for epoll_ctl... yes 
checking for kqueue... no 
checking for port_create... no 
checking for poll... yes 
checking for select... yes 
checking for eventfd... yes 
checking for signalfd... yes 
checking for clock_gettime... no 
checking for clock_gettime syscall... yes 
checking for nanosleep... yes 
checking for library containing floor... -lm 
checking that generated files are newer than configure... done 
configure: creating ./config.status 
config.status: creating Makefile 
config.status: creating config.h 
config.status: executing depfiles commands 
config.status: executing libtool commands 
root <at> YRP-ES-QD:/opt/DevelopmentTraining/Subjects/Libev/libev-4.19# make CROSS_COMPILE=arm-none-linux-gnueabi- ARCH=arm 
make all-am 
make[1]: Entering directory `/opt/DevelopmentTraining/Subjects/Libev/libev-4.19' 
/bin/sh ./libtool --tag=CC --mode=compile arm-none-linux-gnueabi-gcc -DHAVE_CONFIG_H -I. -g -O3 -MT ev.lo -MD -MP -MF .deps/ev.Tpo -c -o ev.lo ev.c 
libtool: compile: arm-none-linux-gnueabi-gcc -DHAVE_CONFIG_H -I. -g -O3 -MT ev.lo -MD -MP -MF .deps/ev.Tpo -c ev.c -fPIC -DPIC -o .libs/ev.o 
ev.c:1314:3: error: #error "memory fences not defined for your architecture, please report" 
ev.c:1625: warning: 'ev_default_loop_ptr' initialized and declared 'extern' 
make[1]: *** [ev.lo] Error 1 
make[1]: Leaving directory `/opt/DevelopmentTraining/Subjects/Libev/libev-4.19' 
make: *** [all] Error 2 


    How can I solve this problem? 
    Appreciate for any response!

libev mailing list
libev <at> lists.schmorp.de
Jamal Hadi Salim | 20 Mar 19:28 2015

clang c11

clang with c11 enforcement (clang -Wall -g -O -std=c11) pukes on:

./ev.c:3814:26: error: use of undeclared identifier 'SIG_UNBLOCK'
             sigprocmask (SIG_UNBLOCK, &sa.sa_mask, 0);
(slightly dated ev.c - but inspecting the latest tree, same issue there)

looking at the man pages for sigprocmask on linux:
sigprocmask() requires one of:

It is trivial to pick one of the above and #define in ev.c but i dont
want to diverge on a private tree.
Is there some compile option perhaps i should be passing to make this go

Nick Zavaritsky | 12 Mar 19:22 2015

Unexpected periodic invocation of ev_check watcher

Dear List,

I have an ev_check watcher in my event loop and it gets invoked approximately every minute or so.
There is no other activity happening and I assume that the loop should just stay idle instead.

Is it the intended behavior?


PS. The code sample.

#include <ev.h>
#include <stdio.h>

void cb(struct ev_loop* loop, struct ev_check* instance, int revents)

int main()
    struct ev_check c;

    ev_check_init(&c, cb);

    ev_check_start(ev_default_loop(0), &c);

    ev_loop(ev_default_loop(0), 0);

    return 0;
Rick van Rein | 14 Feb 15:47 2015

Fwd: Driving a thread pool from libev


> Excellent solution, it indeed avoid memcpy().

Thanks :-D

Conceptually the most logical model would be if libev would run multiple callbacks, each running in
workers from the thread pool; and if it would use this mechanism to avoid starting multiple such callbacks
on a single watcher.

> When you say "yeild()", it's some notification like ev_async_send(), right?

Not quite.  My thinking was that a main thread could spark off multiple callback threads, but these may not
have run when the main thread loops back for another poll() invocation.  This would be sure to give all
sparked-off threads an opportunity to remove the revents from the watcher.  Only threads that don’t act
on their watcher's revents in time would be temporarily removed from the poll() list.  When the threaded
callback finished, they would of course be added back in the poll() list.

The ideal is to run this pthread_yield() once per thread, just before returning to poll() — calling it
from every callback function is possible, but wasteful as a single round over all threads is sufficient
for each invocation of poll().  I don’t know yet if there are macro’s I can define to do that.

I’m thinking even further… the main thread could simply be one from the thread pool.  It would start off
other slaves, until there’s more work then it has slaves for, in which case it would degrade itself to a
slave.  Finishing slaves would take out one further event in turn, until the last is consumed; by that time,
the slave promotes itself to be the new master, and returns to poll().  This makes threads continue to run in
many cases, which means that the opportunity for lock-free or spinlock-based control is high.  Only when a
thread really needs to wait would it be beneficial to wait for locks.  Sort of the “sleeping barber”
setup, where clients volunteer as barbers :)

This stuff is fun :-D

It’s a pitty libev doesn’t do all this yet though; it feels like a natural extension to me.


libev mailing list
libev <at> lists.schmorp.de
Rick van Rein | 14 Feb 10:10 2015

Driving a thread pool from libev


I am trying to drive a thread pool from libev, but the design appears to be impossible; or has anyone no this
list done this before?

The application: a TLS Pool [1], with worker threads that read(), then encrypt or decrypt, then write(). 
The workers should be part of a thread pool.  And, assuming that read() is a bit costly [2], I am trying to do
even that operation in the worker threads.

	[1] http://tlspool.arpa2.net
	[2] when the data is not buffered, and also because data would flow through an intermediate buffer causing
an extra copy operation

When work is offloaded to the thread pool, the callback from libev can return and would hopefully cause
other work to be queued, thus keeping the thread pool occupied with encryption/decryption.  The problem
is, I am not sure if libev will avoid triggering an object that has already been queued, since poll() and
friends will return a read opportunity over and over again.  And AFAIK I cannot tell libev to temporarily
stop calling back on a watcher, except by taking it out completely — which I presume is an expensive operation.

The current design uses a thread for each TLS connection, which is wasteful of memory, and this is why I am
looking to create a thread pool with a limited number of shared workers.  I could decide to do the read() in
the callback, if need be, but have not quite given up on a more efficient approach.  Has anyone on this list
seen such a setup with libev?


Rick van Rein

libev mailing list
libev <at> lists.schmorp.de