ev_async_send() not trigerring corresponding async handler in target loop ?

Pierre-Yves Kerembellec py.kerembellec at gmail.com
Tue Dec 29 13:20:53 CET 2009


Hi list,

I'm quite new to libev and I'm having a hard time figuring out why a call to ev_async_send() will not trigger the corresponding async handler
in the specified target loop. I'm using the following exercizer program, where the main thread basically starts an event loop to monitor network
connections, and then dispatches the accepted client handle in a round-robin way to a bunch of worker threads, which will in turn act like a
very basic HTTP server (libev 2.03 on Ubuntu 9.04): https://pastee.org/5qse7.

When I start this program and "telnet localhost 6666" several times, here is what I get:

$ ./evtest 
WORKER Started 1
WORKER Started 2
WORKER Started 3
WORKER Started 4
MAIN   Started
MAIN   Accept callback
MAIN   Handle 9 sent to thread 1
MAIN   Accept callback
MAIN   Handle 10 sent to thread 2
MAIN   Accept callback
MAIN   Handle 11 sent to thread 3
MAIN   Accept callback
MAIN   Handle 12 sent to thread 4
MAIN   Accept callback
MAIN   Handle 13 sent to thread 1
MAIN   Accept callback
MAIN   Handle 14 sent to thread 2

As you can see, the round-robin distribution to worker threads seems to be fine, but the async_cb is never called. Despite the fact that
I need to add a timer watcher to each worker thread loop (to keep in alive in absence of any other), I've been digging a little but into the
libev code and it seems the internal evpipe_init() function (responsible for creating and initializing a communication eventfd/pipe
associated with the target loop) is never called by ev_async_send(), hence the communication channel is not initialized and the async
watcher is actually never sent. ev_async_start() on the other end will call evpipe_init(), but my understanding is that it's not thread-safe
(because it's not using the communication pipe and changing directly the loop  internal async table from another thread).

Am i missing something here ? Am I using the right workflow ?

For now, I'm back at using my own pipes between the main and the worker threads, adding an ev_io watcher to the reading side of each
pipe, and writing accepted network handles to the pipes in a round-robin way (like the above). I actually mimic the ev_async_send()
behavior, and it works quite fine. But I'd really like to use the provided libev async facility if possible, instead of re-inventing the wheel
in my code.

Thanks for your help,
Pierre-Yves

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.schmorp.de/pipermail/libev/attachments/20091229/12d61679/attachment.html>


More information about the libev mailing list