Fw Lei | 27 Jul 06:59 2014

Can I use ev_async in multiprocess context?

The document of libev gave examples for signal and thread context.

But I want use multiprocess model, in my opinion just put ev_loop and all
watches in shared memory, that will be OK.

My question is, how can I put the default ev_loop into shared memory?

Ramana Yarlagadda | 26 Jun 01:10 2014

read event is not getting triggered


I am using libev in one of my client software module. Client connects to the server. Server sends some information in response to client request.

One of the problems i am seeing here is client socket Event is not getting triggered when the data is available on the client socket.

I know for sure that the server has sent the information requested by the client. So, just to prove that in a timer callback i called the getdata() on the client socket. The getdata() received data on the client socket.

When we send the kill signal we do receive data or the event call back gets triggered.

Has anybody seen similar issue?  can somebody help me here to find a solution.

Following is the skeleton of the client program.

-thanks in advance
class Client {
    void run();

    AMQPWrapper ipc_;
    ev::io io_;
    ev::sig sio_;
    ev::timer timer_;


    ev::default_loop loop;

    timer_.set<Client, &Client::cb_timerEvent>(this);
    timer_.start(1, 0);

    io_.set<Client, &Client::cb_sockEvent>(this);
    io_.start(ipc_.getSocketFD(), ev::READ);




libev mailing list
libev <at> lists.schmorp.de
Nick Zavaritsky | 28 May 08:43 2014

Re: ev_io mode switching performance


> Well, obviously, you need to call a function or macro every time you toggle
> the flags.
> Apart from that, it doesn't matter whether you toggle once or many times per
> event loop iteration - when libev polls for new events, it will tell the
> backend about them.
> For select and poll, the overhead is trivial, for kqueue and epoll, its
> nontrivial and even partially depends on outside events. In the worst
> case, it is one extra syscall per fd with epoll, in the best case, the
> overhead is trivial with epoll.

Thanks a lot!

I am most interested in the epoll backend. Does libev issue a epoll_ctl() for every
io watcher that changed mode in the last iteration or the behavior is somewhat
more sophisticated (i.e. no epoll_ctl() when the ‘initial’ and ‘final’
modes were the same)?
Jan Kaluža | 16 May 08:55 2014

Missing dual-licensing in ecb.h


while packaging libeio for Fedora, I have found out that ecb.h is 
missing GPLv2 part of the license. Is that intentional or you forgot it 

Jan Kaluza
Laska Radek | 6 May 10:43 2014

The special problem of time updates


I have questions about  The special problem of time updates (see

1) There is example in documentation how avoid this. Is this example
correct? I think there should be:
  ev_timer_set (&timer, after  +  (ev_time () - ev_now () ), 0.);
  instead of:
  ev_timer_set (&timer, after + ev_now () - ev_time (), 0.);

2)  It will be nice add ev_time to C++ wrapper (ev++.h). Is it possible
in next version?

Radek Laska
Christian Parpart | 2 May 16:12 2014

libev, multiple threads, and ev_async as notification vs valgrind/helgrind

Hey all,

I am trying to find a race in my threaded app, so I decided to give valgrind+helgrind a try.

My app is spawning N worker threads. each has its own event loop and nicely runs in parallel.
Sometimes one worker needs to wakeup another worker in order to make sure it knows
about something, so I use ev_async_send() for this.

However, even though the man page states (unless I am misreading it) that ev_async is
for this very purpose and is thread safe without any further doing, I get tons of
messages by Valgrind's tool "helgrind" about possible data races.

The race basically occures inside ev_async_send() in thread A, a read operation that is said to
be in conflict to a prior read in the same data region happened inside ev_invoke_pending()+... in thread B.

The Valgrind output about the data race looks like this:

==5023== Possible data race during write of size 4 at 0x76DBB68 by thread #1                                                                                               

==5023== Locks held: 1, at address 0x76B9968
==5023==    at 0x6BBAD70: ev_async_send (in /usr/lib/x86_64-linux-gnu/libev.so.4.0.0)
==5023==    by 0x50E6E28: ev::async::send() (ev++.h:798)
==5023==    by 0x5110D8F: x0::HttpWorker::enqueue(std::pair<x0::Socket*, x0::ServerSocket*>&&) (HttpWorker.cpp:197)
==5023==    by 0x510AAD8: x0::HttpServer::onNewConnection(x0::Socket*, x0::ServerSocket*) (HttpServer.cpp:145)
==5023==    by 0x510D520: void x0::ServerSocket::callback_thunk<x0::HttpServer, &x0::HttpServer::onNewConnection>(x0::Socket*, x0::ServerSocket*) (ServerSocket.h:130)
==5023==    by 0x4E802EC: x0::ServerSocket::acceptOne() (ServerSocket.cpp:705)
==5023==    by 0x4E7F9E9: x0::ServerSocket::accept(ev::io&, int) (ServerSocket.cpp:665)
==5023==    by 0x4E803C2: void ev::base<ev_io, ev::io>::method_thunk<x0::ServerSocket, &x0::ServerSocket::accept>(ev_loop*, ev_io*, int) (ev++.h:479)
==5023==    by 0x6BB5E44: ev_invoke_pending (in /usr/lib/x86_64-linux-gnu/libev.so.4.0.0)
==5023==    by 0x510FE34: x0::HttpWorker::invoke_pending(ev_loop*) (HttpWorker.cpp:51)
==5023==    by 0x6BB8FE6: ev_run (in /usr/lib/x86_64-linux-gnu/libev.so.4.0.0)
==5023==    by 0x5110A3A: ev_loop(ev_loop*, int) (ev.h:826)
==5023==    by 0x51109B2: x0::HttpWorker::run() (HttpWorker.cpp:157)
==5023==    by 0x510ABE3: x0::HttpServer::run() (HttpServer.cpp:225)
==5023==    by 0x4734BD: x0d::XzeroDaemon::run() (XzeroDaemon.cpp:289)
==5023==    by 0x492915: main (x0d.cpp:16)
==5023== This conflicts with a previous read of size 4 by thread #2
==5023== Locks held: 1, at address 0x76DAC28
==5023==    at 0x6BB6BF5: ??? (in /usr/lib/x86_64-linux-gnu/libev.so.4.0.0)
==5023==    by 0x6BB5E44: ev_invoke_pending (in /usr/lib/x86_64-linux-gnu/libev.so.4.0.0)
==5023==    by 0x510FE34: x0::HttpWorker::invoke_pending(ev_loop*) (HttpWorker.cpp:51)
==5023==    by 0x6BB8FE6: ev_run (in /usr/lib/x86_64-linux-gnu/libev.so.4.0.0)
==5023==    by 0x5110A3A: ev_loop(ev_loop*, int) (ev.h:826)
==5023==    by 0x51109B2: x0::HttpWorker::run() (HttpWorker.cpp:157)
==5023==    by 0x5110474: x0::HttpWorker::_run(void*) (HttpWorker.cpp:141)
==5023==    by 0x4C30E26: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)

I hope somebody can tell me that this is a false positive or what I might be missing.

From what I can think of, I should not need any locks at for my threading model, there watchers are only modified inside their respective worker threads *except* the fact, that ev_async is used to notify thread A to thread B to wake up and do some work.

As you may see in the backtrace, I also tried to add a lock around struct ev_loop uses, as shown in the example of the libev man page, in the hope, that maybe I need that part there anyways, but appearently that didn't fix it either.

Any ideas?

Many thanks in advance,
Christian Parpart.
libev mailing list
libev <at> lists.schmorp.de
Nick Zavaritsky | 1 May 23:19 2014

Libev: embeding within a 'foreign' event loop


I realy love the flexibility and the great design of libev, however I am a bit puzzled with the
event loop embeding.

The problem is that I want to mix and match code that uses libev event loop with the code
tailored for a very different event loop environment, all in the same thread.

This other event loop environment is actually Nginx web server. The reason I am willing to jump
through hoops is because of the piece of code that is to be used both in a standalone utility and
in a Nginx module.

Nginx event loop provides utilities to watch file descriptors for status changes. Timers are also
included. It's safe to assume that epoll is used for fd watching on the target platform.

I think it is relatively easy to embed nginx event loop inside ev_loop with but the pair of watchers:
ev_io for the epoll fd plus ev_timer (or maybe ev_prepare and ev_check should be added to the mix
as well?)

There is one thing that still bothers me: now it takes two epoll_wait() calls for Nginx to fetch the events
instead of one. (One epoll_wait() in libev plus another epoll_wait() for the nested epoll fd maintained
solely by Nginx). Though the overhead is probably negligible I would prefer to have it another
way around, i.e. let Nginx control the 'outermost' event loop while libev drives the embeded loop.

Is this possible with libev?

For example libuv has uv_backend_fd() and uv_backend_timeout(); but I can't find anything
similar in libev.
李晓岚 | 1 May 10:33 2014

Fork watcher will not be called if fork() is invoked in prepare watcher callback.

Hi, there,
Considering this scenario, loop_init called without EVFLAG_FORKCHECK,
then register some fork and prepare watchers and start them. At a
certain point, in prepare watcher callback fork() is called, and in
child process ev_loop_fork() is also called honestly. Oops, the
callbacks of fork watcher will never be fired.
According to the source code, ev_loop_fork() just set a flag
postfork=1, and the following loop_fork() call clears this flag before
the next loop until which fork watchers are examined.
Is this behavior is intended with any considerations or a bug?
Assaf Inbal | 25 Apr 14:34 2014

Re: libev doesn't notify on read event (file FD and timers)

> I'll take care of it, but indeed, that's the code that generates the
> event.  It does rely on the undocumented behaviour of EPOLL returning
> eperm on regular files (but whats not undocumented in epoll...), but the
> problem is caused by your watchers using the same fd, and while libev
> removes the emulation for the fd on the first ev_io_stop, it doesn't add
> it back on the next ev_io_start, which is a bug in not clearing the epoll
> event mask (EV_EMASK_EPERM).

Just one more question, if the issue is because the mask isn't cleared
for the FD, why does it work without the timer in the sample code I
attached before, I still call ev_io_stop on the first FD, and then
ev_io_start on the next.
Assaf Inbal | 24 Apr 10:30 2014

Fwd: libev doesn't notify on read event (file FD and timers)

Hey all,

I'm using libev as a part of a larger project. In this project I have a library that does some asynchronous work directly over FDs and timers. While I understand that it's not exactly recommended, these FDs can also be of local files as well as sockets.

As a part of the process, I have an EV_READ event set on a file, in that handler I stop the event handler and close the FD. I then set a timer and in that timer, open another file and set a read event on it.
The issue is that the read event on the second file is never called.
I've attached a sample code file to show this happening.
I'm using libev 4.11 on Ubuntu 12.04 LTS compiling with gcc as follows: gcc ev_test.c -o ev_test -lev
I also tried to locally compile 4.15 but the issue reproduced there as well (assuming I did so correctly).

It's worth mentioning that if I disable the timer and create the second read event in the first's handler (undef USE_TIMER) everything works as expected.
I also tried not closing the FD (commenting out line 36), thus making the second file get a different FD, and that also worked.
Changing the timeout value from 0 to anything else didn't help.

Can anyone please tell me why this happens? Or, better yet, how I can fix it?


Attachment (ev_test.c): text/x-csrc, 1657 bytes
libev mailing list
libev <at> lists.schmorp.de
Vinubalaji Gopal | 16 Apr 23:33 2014

libev port crash in solaris

  I see the port based implementation crashes in solaris. I am running the latest Solaris (based on the archive suggestions) but it still seem to crash. I did find a case where it crashes immediately (which is good, otherwise it crashes randomly). Any ideas on what could be causing this?

-----------------  lwp# 21 / thread# 21  --------------------

 ffffffff7dedcb68 _lwp_kill (6, 0, ffffffff7e049c68, ffffffffffffffff, ffffffff7e03e000, 0) + 8

 ffffffff7de4c1c0 abort (1, 1d8, 0, 1f1f4c, 0, 0) + 118

 00000001000f7d50 ev_syserr (100495020, 1, 40, ffffffff7b1f12bc, 3e, f7) + 78

 00000001000f9418 port_poll (1046ed6d0, 4, 1046ed878, 5, 0, 1046effc0) + 14c

 00000001000fcb50 ev_run (1046ed6d0, 0, 104674df8, ffffffffffffffff, 0, 0) + 4bc

 000000010009f0f0 ev_loop (1046ed6d0, 0, ffffffff7b1f15c0, ffffffff7b1f15f0, 1, 0) + 20

bash-3.2# uname -a

SunOS sol220 5.10 Generic_147147-26 sun4u sparc SUNW,Sun-Fire-V210

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