Is that ev_run()/ev_loop() inhibited in multiple thread of current libev?

freebsdj freebsdj at
Wed Dec 21 18:58:52 CET 2011

I apologise if this question's been asked before -- I've searched
around, but found nothing.

I use libev to notify IO event in my project.

My project is a networking server, I have an assign thread to accept
connections and
dispatch fd to query threads, both assign thread and query threads are
using ev_run()
to wait new connections:

              [main thread] ---> struct ev_loop* global_loop =
                      |---> pthread_create()
             [assign thread] ---> ev_io_init() --> ev_io_start(global_loop)
--> ev_run(global_loop, 0)
                      |---> pthread_create() <several times>
             [query threads] ---> ev_io_init() --> ev_io_start(global_loop)
--> ev_run(global_loop, 0)

The issue is that it will crash while calling ev_run() in query thread,
with the message:
"libev: ev_loop recursion during release detected".

I noticed that the description in manual: better to create a new ev_loop in
every thread, but according
to my experiences of using libev in 2009, I can do that.

I have took a look at the code in ev_run(), that assert() judge the value
of loop->loop_done, and this field
is modified in another assertion:
        assert ((loop_done = EVUNLOOP_RECURSE, 1)); /* assert for side
effect */
        assert ((loop_done = EVUNLOOP_CANCEL, 1)); /* assert for side
effect */

My question is:
1. Can I use ev_loop() in multi-threads environment(though not preferred)?
2. Why check the loop->loop_done there?
3. If I compiled with -DNDEBUG, all the assert()s are ignored, so it will
not crash, but it doesn't seems work
correctly. Is that an inappropriate design to put code in assertions?

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the libev mailing list