Raphael 'kena' Poss | 8 Sep 21:58 2014

Bug in C++ wrapper

Dear all,

ev.h since modified in 4.15 is currently invalid when used from C++: it includes exception information
(throw()) for the typedef ev_loop_callback_nothrow, which is not legal in C++.

throw() is not part of a function's type, so it cannot be captured by typedef.

The correct fix is to remove EV_THROW on that particular typedef.

Best regards,


Raphael 'kena' Poss · r.poss <at> uva.nl

libev mailing list
libev <at> lists.schmorp.de
Ani A | 8 Sep 09:11 2014

Regarding: undefined symbol: ev_default_loop_ptr


while I was trying to use libev, with lua-ev library, I got this
undefined symbol error,
I tried to search for solutions but I found only one discussion on a
Node.js forum related to the optimization (-O0 vs -O2)
I am not sure what is the correct option I should be using.

I tried to build libev.so from source as well (libev-4.18.tar.gz and
CFLAGS="-O0" )
still saw the same error

Can anyone please suggest what options (compile/linker) that I need to use.

I am on Ubuntu 12.04 LTS
gcc version 4.6.3

Marc Lehmann | 5 Sep 18:50 2014

libev-4.18 has just been released

I am pleased to announce libev 4.18!

Distribution: http://dist.schmorp.de/libev/libev-4.18.tar.gz
Documentation: http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod?pathrev=rel-4_18
Changes: http://cvs.schmorp.de/libev/Changes?pathrev=rel-4_18

This release is mainly a bugfix release. Unless you are directly affected
by one of the fixes, there is no urgent need to upgrade.

The complete Changes are:

4.18 Fri Sep  5 17:55:26 CEST 2014
        - events on files were not always generated properly with the
          epoll backend (testcase by Assaf Inbal).
        - mark event pipe fd as cloexec after a fork (analyzed by Sami Farin).
        - (ecb) support m68k, m88k and sh (patch by Miod Vallat).
        - use a reasonable fallback for EV_NSIG instead of erroring out
          when we can't detect the signal set size.
        - in the absence of autoconf, do not use the clock syscall
          on glibc >= 2.17 (avoids the syscall AND -lrt on systems
          doing clock_gettime in userspace).
        - ensure extern "C" function pointers are used for externally-visible
          loop callbacks (not watcher callbacks yet).
        - (ecb) work around memory barriers and volatile apparently both being
          broken in visual studio 2008 and later (analysed and patch by Nicolas Noble).


                The choice of a       Deliantra, the free code+content MORPG
      -----==-     _GNU_              http://www.deliantra.net
      ----==-- _       generation
(Continue reading)

Aviv Heller (avheller | 21 Aug 15:33 2014

Timers expire prior to expiry time


I have encountered a problem, on version 4.11 of the library, where a timer started expired prior to its intended expiry time.

This happened because time_update() is not called by ev_timer_start() prior to calculating the expiry timestamp, which in cases where a timer is started after a long processing time during a loop iteration, results in ev_timer_start() using an old time instead of the current one.

In cases where the system is under heavy load (a prevalent case in embedded systems), this problem can manifest even if the iteration processing time prior to setting the timer is in theory short.

The fix I propose is to have ev_timer_start() call time_update() before calculating the expiry timestamp (patch attached).

I would be glad to know what are your thoughts on this issue, and whether this fix is needed and makes sense.


Attachment (libev-time-update-on-timer-start.patch): application/octet-stream, 738 bytes
libev mailing list
libev <at> lists.schmorp.de
Hongli Lai | 4 Aug 09:02 2014

Patch: fix libeio cancellation

According to the libeio documentation, the callback will still be
called even if the request has been cancelled. The libeio code checks
for the cancel flag, and does not call the callback if it's set. This
happens even if the system call has already finished.

The attached patch fixes the problem.


Phusion | Web Application deployment, scaling, and monitoring solutions

Web: http://www.phusion.nl/
E-mail: info <at> phusion.nl
Chamber of commerce no: 08173483 (The Netherlands)
Attachment (fix_eio_cancel.patch): application/octet-stream, 474 bytes
libev mailing list
libev <at> lists.schmorp.de
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